[XP] XP Ace Tilemap

Started by KK20, November 02, 2014, 05:53:24 am

Previous topic - Next topic

Blizzard

January 07, 2016, 01:12:54 pm #60 Last Edit: January 07, 2016, 01:54:32 pm by Blizzard
I'm kinda working on Beyond Epic mode in CP. xD
I tried XPA to boost the performance, but I was having problems with the windowskin converter (and found that Window#opacity=0 doesn't hide that waiting arrow in messages, RGSS3 bug probably). When I swithed back to XP, I noticed this bug since I decided to keep this script.

EDIT: Ok, adding that part below #KK20 seemed to fix it. Is there an equivalent for Tilemap#ox= needed? I can see some code that should be doing the same thing, but I'd rather ask.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

I believe there shouldn't be a need for ox=.

The reason why it occurs in oy= is because of the tiles that have priority. I made these tiles be drawn on SCREN_WIDTH x 160 sized-sprites. The way the DLL works is that it draws all the tiles in a row as it comes into the player's view. Because of that, I forgot to dispose of the row of tiles and it just blts the same tiles over the pre-existing ones.

For ox=, it's mainly just shifting the bitmap bytes left or right and clears the appropriate column before drawing that column with the new tiles. Hopefully that all made sense.

(I'll also have to look at that Window#opacity when I have the time. There is a script that I found and used in Advance Wars Engine that rewrites windows using sprites--could probably try checking that out.)

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

Yeah, it makes sense, I know what you are talking about. xD

About that window problem, I encountered it in a custom Window class that uses that waiting cursor (similar to Window_Message), but I used only self.opacity and no self.visible to show/hide it. It's visible all the time. And while it's visible, that waiting cursor at the bottom is always visible. It seems that it ignores self.opacity in the Window class in RGSS3 so I'm pretty sure it's an RGSS3 bug.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

Oh wait a minute, it just occurred to me. I think there's a separate method for that. Did you look in the RMVXA help file? Of course I'm at work so I have no means to look myself.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

There is? Aw man. ._. Seems kinda pointless to have it separate. No, I didn't look it up.
Regardless, the cursor rendering didn't work well either in a few specific windows with horizontally aligned menu items.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

January 08, 2016, 02:00:58 am #65 Last Edit: January 08, 2016, 02:28:44 am by KK20
ayyy, I was right:
arrows_visible (RGSS3)
The visibility of scrolling arrows. If TRUE, the arrows are visible. The default is TRUE.

But le sad face. No more XPA :[

EDIT: Finally found it: http://forum.chaos-project.com/index.php/topic,14219.msg185568.html#msg185568
Not sure if this is what you mentioned about the cursor not aligning. This addresses the issue where, if you wish to view more contents of your window and want to scroll, the cursor would just happen to get stuck where it's at. Then wonky shit happens:
Spoiler: ShowHide



I guess RGSS3 doesn't like the use of self.ox/oy anymore, so those have to be removed.

But the WindowPadding and WindowSkin scripts seem to do their job for me. Are your windows just super unique? xP

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

January 08, 2016, 03:54:38 am #66 Last Edit: January 08, 2016, 05:06:54 am by Blizzard
WindowPadding works fine. WindowSkin required me to remove some code in order to work. I only left the bare minimum.
Yeah, it's possible that ox and oy are causing the problem. It does manifest in a different way in my case, but something's definitely off. I'll try to remove ox and oy and see what happens.

EDIT: Nope, it breaks everything so I put ox and oy back in.
This is what happens usually:

the one instance where it's correct: ShowHide

when pressing left once: ShowHide

when pressing right once: ShowHide


This window is implemented by moving it left right as well as offsetting the cursor coordinate. Here's the code if you wanna check it out.

Spoiler: ShowHide
class Window_Horizontal < Window_Base
 
  attr_reader :commands
 
  def initialize(w, commands)
    super(0, 0, 3 * w + 32, 64)
    @item_max = commands.size
    @commands = commands
    if @item_max > 0
      self.contents = Bitmap.new((@item_max + 4) * w, height - 32)
    else
      self.contents = Bitmap.new(32, height - 32)
    end
    @dir = 0
    self.contents.font.name, self.contents.font.size = 'Brush Script', 26
    self.opacity = self.index = 0
    refresh
  end
 
  def refresh
    self.contents.clear
    (0...@item_max+4).each {|i| draw_item(i, (i + @item_max - 2) % @item_max)}
  end
 
  def get_command
    return @commands[(@index + @item_max) % @item_max]
  end
 
  def draw_item(i, index, color = nil)
    rect = Rect.new((self.width - 32)/3 * i, 0, (self.width - 32)/3, 32)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    if color.is_a?(Color)
      self.contents.font.color = color
    else
      self.contents.font.color = case @commands[index]
      when 'And again!' then text_color(3)
      when 'Warrior' then text_color(6)
      when 'Exerion' then text_color(2)
      when 'Beyond Epic' then text_color(11)
      when 'Controls' then text_color(9)
      when 'Credits' then text_color(10)
      else
        normal_color
      end
    end
    self.contents.draw_text_outline(rect, @commands[index], 1)
  end
 
  def disable_item(index)
    draw_item((index + 2) % @item_max, index, disabled_color)
    draw_item((index + 2) % @item_max + @item_max, index, disabled_color)
    draw_item((index + 2) % @item_max + @item_max*2, index, disabled_color)
  end
 
  def size
    return @commands.size
  end
 
  def update
    super
    if moving?
      case @dir.abs
      when 1 then self.ox -= 5 * @dir.sgn
      when 2 then self.ox -= 10 * @dir.sgn
      when 3 then self.ox -= 20 * @dir.sgn
      when 4 then self.ox -= 45 * @dir.sgn
      when 5 then self.ox -= 45 * @dir.sgn
      when 6 then self.ox -= 20 * @dir.sgn
      when 7 then self.ox -= 10 * @dir.sgn
      when 8 then self.ox -= 5 * @dir.sgn
      end
      @dir -= @dir.sgn
    end
    if !moving? && self.active && @item_max > 0
      if Input.repeat?($controls.right)
        $game_system.se_play($data_system.cursor_se)
        @index = @index % @item_max + 1
        if self.ox == (@item_max + 1)* (self.width - 32)/3
          self.ox -= @item_max * (self.width - 32)/3
          @index = 1
        end
        @dir = -8
      elsif Input.repeat?($controls.left)
        $game_system.se_play($data_system.cursor_se)
        @index = (@index + @item_max - 2) % @item_max + 1
        if self.ox == (self.width - 32)/3
          self.ox += @item_max * (self.width - 32)/3
          @index = @item_max - 1
        end
        @dir = 8
      end
    end
    update_cursor_rect
  end
 
  def moving?
    return (@dir != 0)
  end
     
  def index=(index)
    @index = index
    self.ox = (index + 1) * (self.width - 32)/3
    update_help if self.active && @help_window != nil
    update_cursor_rect
  end
 
  def update_cursor_rect
    self.cursor_rect.set((self.width - 32)/3, 0, (self.width - 32)/3, 32)
  end
 
end
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20


  def update_cursor_rect
    self.cursor_rect.set(self.ox + 160, 0, (self.width - 32)/3, 32)
  end

:P

Also, for the whole "opacity = 0 makes the scroll arrows disappear", it doesn't work in vanilla XP. I just tried making a new project, gave player all the items, set Window_Item opacity to zero in initialize, and...arrow:

So I think that's something unique to your window modification script only.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

Not scroll arrows. The waiting arrow.

As for that code, does this mean that I have to change all update_cursor_rect implementations?
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

Oh, I guess I was under the impression that the scrolling arrows were being used instead or something. In that case, I don't understand why you don't use the Window attribute:
pause
The pause graphic's visibility. This is a symbol that appears in the message window when waiting for the player to press a button. If TRUE, the graphic is visible. The default is FALSE.

The cursor rect does handle much differently now. Rather than being a separate entity, (like another sprite) it's almost like it's being drawn in the window contents itself. If the cursor behaves like a normal window_selectable/command, just do what Drago did in the link I posted earlier (removing self.ox/oy from the equation). If it's more strict, like your horizontal window, you'll have to implement self.ox/oy into the equation.

I've never really looked hard into that problem before, so I'm not sure how feasible a "fix-all" solution is.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

Aha, I understand now what you're trying to tell me. Alright, I'll check it out. I added a $XPA variable in my code so I can easily switch back and forth if XPA causes too many bugs or something.

I also remember that I had some weird freezing when entering certain maps in my game when using XPA, but I have to look into that first.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

Alright, I think I found the window cursor fix. Granted, you need to add Selwyn's Window Rewrite script as well as remove the WindowSkin fix. Also, you'll now get an error for the padding fix. But I took liberty upon myself to just provide a one script fix-all (I think):

#==============================================================================
# ? Window - Hidden RGSS Class - XPA Compatibility Version
#------------------------------------------------------------------------------
# ?by Selwyn
# Edit by KK20
#==============================================================================

#==============================================================================
# ? Bitmap
#==============================================================================

class Bitmap
  #--------------------------------------------------------------------------
  # ? erase
  #--------------------------------------------------------------------------
  def erase(*args)
    if args.size == 1
      rect = args[0]
    elsif args.size == 4
      rect = Rect.new(*args)
    end
    fill_rect(rect, Color.new(0, 0, 0, 0))
  end
end

#==============================================================================
# ? SG::Skin
#==============================================================================

class Skin
  #--------------------------------------------------------------------------
  # ? instances settings
  #--------------------------------------------------------------------------
  attr_reader   :margin
  attr_accessor :bitmap
  #--------------------------------------------------------------------------
  # ? initialize
  #--------------------------------------------------------------------------
  def initialize
    @bitmap = nil
    @values = {}
    @values['bg'] = Rect.new(0, 0, 128, 128)
    @values['pause0'] = Rect.new(160, 64, 16, 16)
    @values['pause1'] = Rect.new(176, 64, 16, 16)
    @values['pause2'] = Rect.new(160, 80, 16, 16)
    @values['pause3'] = Rect.new(176, 80, 16, 16)
    @values['arrow_up'] = Rect.new(152, 16, 16, 8)
    @values['arrow_down'] = Rect.new(152, 40, 16, 8)
    @values['arrow_left'] = Rect.new(144, 24, 8, 16)
    @values['arrow_right'] = Rect.new(168, 24, 8, 16)
    self.margin = 16
  end
  #--------------------------------------------------------------------------
  # ? width
  #--------------------------------------------------------------------------
  def margin=(width)
    @margin = width
    set_values
  end
  #--------------------------------------------------------------------------
  # ? set_values
  #--------------------------------------------------------------------------
  def set_values
    w = @margin
    @values['ul_corner'] = Rect.new(128, 0, w, w)
    @values['ur_corner'] = Rect.new(192-w, 0, w, w)
    @values['dl_corner'] = Rect.new(128, 64-w, w, w)
    @values['dr_corner'] = Rect.new(192-w, 64-w, w, w)
    @values['up'] = Rect.new(128+w, 0, 64-2*w, w)
    @values['down'] = Rect.new(128+w, 64-w, 64-2*w, w)
    @values['left'] = Rect.new(128, w, w, 64-2*w)
    @values['right'] = Rect.new(192-w, w, w, 64-2*w)
  end
  #--------------------------------------------------------------------------
  # ? []
  #--------------------------------------------------------------------------
  def [](value)
    return @values[value]
  end
end


#==============================================================================
# ? SG::Cursor_Rect
#==============================================================================

class Cursor_Rect < ::Sprite
  #--------------------------------------------------------------------------
  # ? instances settings
  #--------------------------------------------------------------------------
  attr_reader   :height, :width, :skin, :margin
  #--------------------------------------------------------------------------
  # ? initialize
  #--------------------------------------------------------------------------
  def initialize(viewport, parent_window)
    super(viewport)
    @window = parent_window
    @width = 0
    @height = 0
    @skin = nil
    @margin = 0
    @rect = {}
    @rect['cursor_up'] = Rect.new(129, 64, 30, 1)
    @rect['cursor_down'] = Rect.new(129, 95, 30, 1)
    @rect['cursor_left'] = Rect.new(128, 65, 1, 30)
    @rect['cursor_right'] = Rect.new(159, 65, 1, 30)
    @rect['upleft'] = Rect.new(128, 64, 1, 1)
    @rect['upright'] = Rect.new(159, 64, 1, 1)
    @rect['downleft'] = Rect.new(128, 95, 1, 1)
    @rect['downright'] = Rect.new(159, 95, 1, 1)
    @rect['bg'] = Rect.new(129, 65, 30, 30)
  end
  #--------------------------------------------------------------------------
  # ? margin=
  #--------------------------------------------------------------------------
  def margin=(margin)
    @margin = margin
    set(x, y, width, height)
  end
  #--------------------------------------------------------------------------
  # ? skin=
  #--------------------------------------------------------------------------
  def skin=(skin)
    @skin = skin
    draw_rect
  end
  #--------------------------------------------------------------------------
  # ? width=
  #--------------------------------------------------------------------------
  def width=(width)
    return if @width == width
    @width = width
    if @width == 0 and self.bitmap != nil
      self.bitmap.dispose
      self.bitmap = nil
    end
    draw_rect
  end
  #--------------------------------------------------------------------------
  # ? height=
  #--------------------------------------------------------------------------
  def height=(height)
    return if @height == height
    @height = height
    if @height == 0 and self.bitmap != nil
      self.bitmap.dispose
      self.bitmap = nil
    end
    draw_rect
  end
  #--------------------------------------------------------------------------
  # ? set
  #--------------------------------------------------------------------------
  def set(x, y, width, height)
    self.x = x + @margin
    self.y = y + @margin
    if @width != width or @height != height
      @width = width
      @height = height
      if width > 0 and height > 0
        draw_rect
      end
    end
  end
  #--------------------------------------------------------------------------
  # ? empty
  #--------------------------------------------------------------------------
  def empty
    self.x = 0
    self.y = 0
    self.width = 0
    self.height = 0
  end
  #--------------------------------------------------------------------------
  # ? draw_rect
  #--------------------------------------------------------------------------
  def draw_rect
    return if @skin == nil
    if @width > 0 and @height > 0
      self.bitmap = Bitmap.new(@width, @height)
      rect = Rect.new(1, 1, @width - 2, @height - 2)
      self.bitmap.stretch_blt(rect, @skin, @rect['bg'])
      self.bitmap.blt(0, 0, @skin, @rect['upleft'])
      self.bitmap.blt(@width-1, 0, @skin, @rect['upright'])
      self.bitmap.blt(0, @height-1, @skin, @rect['downright'])
      self.bitmap.blt(@width-1, @height-1, @skin, @rect['downleft'])
      rect = Rect.new(1, 0, @width - 2, 1)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_up'])
      rect = Rect.new(0, 1, 1, @height - 2)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_left'])
      rect = Rect.new(1, @height-1, @width - 2, 1)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_down'])
      rect = Rect.new(@width - 1, 1, 1, @height - 2)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_right'])
    end
  end
end

#==============================================================================
# ? SG::Window
#------------------------------------------------------------------------------
# ?
#==============================================================================

class Window
  #--------------------------------------------------------------------------
  # ? set instances variables
  #--------------------------------------------------------------------------
  attr_reader(:x, :y, :z, :width, :height, :ox, :oy, :opacity, :back_opacity,
              :stretch, :contents_opacity, :visible, :pause)
  attr_accessor :active
  #--------------------------------------------------------------------------
  # ? initialize
  #--------------------------------------------------------------------------
  def initialize()
    @skin = Skin.new
    @viewport = Viewport.new(0, 0, 0, 0)
    @cr_vport = Viewport.new(0, 0, 0, 0)
    @width = 0
    @height = 0
    @ox = 0
    @oy = 0
    @opacity = 255
    @back_opacity = 255
    @contents_opacity = 255
    @frame   = Sprite.new()
    @bg      = Sprite.new()
    @window  = Sprite.new(@viewport)
    @pause_s = Sprite.new()
    @arrows = []
    for i in 0...4
      @arrows.push(Sprite.new(@cr_vport))
      @arrows[i].bitmap = Bitmap.new(16, 16)
      @arrows[i].visible = false
    end
    @cursor_rect = Cursor_Rect.new(@cr_vport, self)
    @cursor_rect.margin = @skin.margin
    @cursor_fade = true
    @pause_s.visible = false
    @pause = false
    @active = true
    @stretch = true
    @visible = true
    self.x = 0
    self.y = 0
    self.z = 100
    self.windowskin = RPG::Cache.windowskin($game_system.windowskin_name)
  end
  #--------------------------------------------------------------------------
  # ? contents=
  #--------------------------------------------------------------------------
  def contents=(bmp)
    @window.bitmap = bmp
    if bmp != nil
      if bmp.width > @viewport.rect.width
         bmp.height > @viewport.rect.height
        draw_arrows
      end
    end
  end
  #--------------------------------------------------------------------------
  # ? contents
  #--------------------------------------------------------------------------
  def contents
    return @window.bitmap
  end
  #--------------------------------------------------------------------------
  # ? dispose
  #--------------------------------------------------------------------------
  def dispose
    @bg.dispose
    @frame.dispose
    @window.dispose
    @cursor_rect.dispose
    @viewport.dispose
    @pause_s.dispose
    @cr_vport.dispose
    for arrow in @arrows
      arrow.dispose
    end
  end
  #--------------------------------------------------------------------------
  # ? update
  #--------------------------------------------------------------------------
  def update
    @window.update
    @cursor_rect.update
    @viewport.update
    @cr_vport.update
    @pause_s.src_rect = @skin["pause#{(Graphics.frame_count / 8) % 4}"]
    @pause_s.update
    update_visible
    update_arrows
    if @cursor_fade
      @cursor_rect.opacity -= 10
      @cursor_fade = false if @cursor_rect.opacity <= 100
    else
      @cursor_rect.opacity += 10
      @cursor_fade = true if @cursor_rect.opacity >= 255
    end
  end
  #--------------------------------------------------------------------------
  # ? update_visible
  #--------------------------------------------------------------------------
  def update_visible
    @frame.visible = @visible
    @bg.visible = @visible
    @window.visible = @visible
    @cursor_rect.visible = @visible
    if @pause
      @pause_s.visible = @visible
    else
      @pause_s.visible = false
    end
  end
  #--------------------------------------------------------------------------
  # ? pause=
  #--------------------------------------------------------------------------
  def pause=(pause)
    @pause = pause
    update_visible
  end
  #--------------------------------------------------------------------------
  # ? update_arrows
  #--------------------------------------------------------------------------
  def update_arrows
    if @window.bitmap == nil or @visible == false
      for arrow in @arrows
        arrow.visible = false
      end
    else
      @arrows[0].visible = @oy > 0
      @arrows[1].visible = @ox > 0
      @arrows[2].visible = (@window.bitmap.width - @ox) > @viewport.rect.width
      @arrows[3].visible = (@window.bitmap.height - @oy) > @viewport.rect.height
    end
  end
  #--------------------------------------------------------------------------
  # ? visible=
  #--------------------------------------------------------------------------
  def visible=(visible)
    @visible = visible
    update_visible
    update_arrows
  end
  #--------------------------------------------------------------------------
  # ? x=
  #--------------------------------------------------------------------------
  def x=(x)
    @x = x
    @bg.x = x + 2
    @frame.x = x
    @viewport.rect.x = x + @skin.margin
    @cr_vport.rect.x = x
    @pause_s.x = x + (@width / 2) - 8
    set_arrows
  end
  #--------------------------------------------------------------------------
  # ? y=
  #--------------------------------------------------------------------------
  def y=(y)
    @y = y
    @bg.y = y + 2
    @frame.y = y
    @viewport.rect.y = y + @skin.margin
    @cr_vport.rect.y = y
    @pause_s.y = y + @height - @skin.margin
    set_arrows
  end
  #--------------------------------------------------------------------------
  # ? z=
  #--------------------------------------------------------------------------
  def z=(z)
    @z = z
    @bg.z = z
    @frame.z = z + 1
    @cr_vport.z = z + 2
    @viewport.z = z + 3
    @pause_s.z = z + 4
  end
  #--------------------------------------------------------------------------
  # ? ox=
  #--------------------------------------------------------------------------
  def ox=(ox)
    return if @ox == ox
    @ox = ox
    @viewport.ox = ox
    update_arrows
  end
  #--------------------------------------------------------------------------
  # ? oy=
  #--------------------------------------------------------------------------
  def oy=(oy)
    return if @oy == oy
    @oy = oy
    @viewport.oy = oy
    update_arrows
  end
  #--------------------------------------------------------------------------
  # ? width=
  #--------------------------------------------------------------------------
  def width=(width)
    @width = width
    @viewport.rect.width = width - @skin.margin * 2
    @cr_vport.rect.width = width
    if @width > 0 and @height > 0
      @frame.bitmap = Bitmap.new(@width, @height)
      @bg.bitmap = Bitmap.new(@width - 4, @height - 4)
      draw_window
    end
    self.x = @x
    self.y = @y
  end
  #--------------------------------------------------------------------------
  # ? height=
  #--------------------------------------------------------------------------
  def height=(height)
    @height = height
    @viewport.rect.height = height - @skin.margin * 2
    @cr_vport.rect.height = height
    if @height > 0 and @width > 0
      @frame.bitmap = Bitmap.new(@width, @height)
      @bg.bitmap = Bitmap.new(@width - 4, @height - 4)
      draw_window
    end
    self.x = @x
    self.y = @y
  end
  #--------------------------------------------------------------------------
  # ? opacity=
  #--------------------------------------------------------------------------
  def opacity=(opacity)
    value = [[opacity, 255].min, 0].max
    @opacity = value
    @contents_opacity = value
    @back_opacity = value
    @frame.opacity = value
    @bg.opacity = value
    @window.opacity = value
  end
  #--------------------------------------------------------------------------
  # ? back_opacity=
  #--------------------------------------------------------------------------
  def back_opacity=(opacity)
    value = [[opacity, 255].min, 0].max
    @back_opacity = value
    @bg.opacity = value
  end
  #--------------------------------------------------------------------------
  # ? contents_opacity=
  #--------------------------------------------------------------------------
  def contents_opacity=(opacity)
    value = [[opacity, 255].min, 0].max
    @contents_opacity = value
    @window.opacity = value
  end
  #--------------------------------------------------------------------------
  # ? cursor_rect
  #--------------------------------------------------------------------------
  def cursor_rect
    return @cursor_rect
  end
  #--------------------------------------------------------------------------
  # ? cursor_rect=
  #--------------------------------------------------------------------------
  def cursor_rect=(rect)
    @cursor_rect.x = rect.x
    @cursor_rect.y = rect.y
    if @cursor_rect.width != rect.width or @cursor_rect.height != rect.height
      @cursor_rect.set(@cursor_rect.x, @cursor_rect.y, rect.width, rect.height)
    end
  end
  #--------------------------------------------------------------------------
  # ? windowskin
  #--------------------------------------------------------------------------
  def windowskin
    return @skin.bitmap
  end
  #--------------------------------------------------------------------------
  # ? windowskin=
  #--------------------------------------------------------------------------
  def windowskin=(windowskin)
    return if windowskin == nil
    if @skin.bitmap != windowskin
      @pause_s.bitmap = windowskin
      @pause_s.src_rect = @skin['pause0']
      @skin.bitmap = windowskin
      @cursor_rect.skin = windowskin
      draw_window
      draw_arrows
    end
  end
  #--------------------------------------------------------------------------
  # ? padding=
  #--------------------------------------------------------------------------
  alias set_padding padding=
  def padding=(pad)
    return if self.disposed?
    set_padding(pad)
    self.margin = pad
  end
  #--------------------------------------------------------------------------
  # ? margin=
  #--------------------------------------------------------------------------
  def margin=(margin)
    if @skin.margin != margin
      @skin.margin = margin
      self.x = @x
      self.y = @y
      temp = @height
      self.height = 0
      self.width = @width
      self.height = temp
      @cursor_rect.margin = margin
      set_arrows
    end
  end
  #--------------------------------------------------------------------------
  # ? stretch=
  #--------------------------------------------------------------------------
  def stretch=(bool)
    if @stretch != bool
      @stretch = bool
      draw_window
    end
  end
  #--------------------------------------------------------------------------
  # ? set_arrows
  #--------------------------------------------------------------------------
  def set_arrows
    @arrows[0].x = @width / 2 - 8
    @arrows[0].y = 8
    @arrows[1].x = 8
    @arrows[1].y = @height / 2 - 8
    @arrows[2].x = @width - 16
    @arrows[2].y = @height / 2 - 8
    @arrows[3].x = @width / 2 - 8
    @arrows[3].y = @height - 16
  end
  #--------------------------------------------------------------------------
  # ? draw_arrows
  #--------------------------------------------------------------------------
  def draw_arrows
    return if @skin.bitmap == nil
    @arrows[0].bitmap.blt(0, 0, @skin.bitmap, @skin['arrow_up'])
    @arrows[1].bitmap.blt(0, 0, @skin.bitmap, @skin['arrow_left'])
    @arrows[2].bitmap.blt(0, 0, @skin.bitmap, @skin['arrow_right'])
    @arrows[3].bitmap.blt(0, 0, @skin.bitmap, @skin['arrow_down'])
    update_arrows
  end
  #--------------------------------------------------------------------------
  # ? draw_window
  #--------------------------------------------------------------------------
  def draw_window
    return if @skin.bitmap == nil
    return if @width == 0 or @height == 0
    m = @skin.margin
    if @frame.bitmap.nil?
      @frame.bitmap = Bitmap.new(@width, @height)
      @bg.bitmap = Bitmap.new(@width - 4, @height - 4)
    end
    @frame.bitmap.clear
    @bg.bitmap.clear
    if @stretch
      dest_rect = Rect.new(0, 0, @width-4, @height-4)
      @bg.bitmap.stretch_blt(dest_rect, @skin.bitmap, @skin['bg'])
    else
      bgw = Integer((@width-4) / 128) + 1
      bgh = Integer((@height-4) / 128) + 1
      for x in 0..bgw
        for y in 0..bgh
          @bg.bitmap.blt(x * 128, y * 128, @skin.bitmap, @skin['bg'])
        end
      end
    end
    bx = Integer((@width - m*2) / @skin['up'].width) + 1
    by = Integer((@height - m*2) / @skin['left'].height) + 1
    for x in 0..bx
      w = @skin['up'].width
      @frame.bitmap.blt(x * w + m, 0, @skin.bitmap, @skin['up'])
      @frame.bitmap.blt(x * w + m, @height - m, @skin.bitmap, @skin['down'])
    end
    for y in 0..by
      h = @skin['left'].height
      @frame.bitmap.blt(0, y * h + m, @skin.bitmap, @skin['left'])
      @frame.bitmap.blt(@width - m, y * h + m, @skin.bitmap, @skin['right'])
    end
    @frame.bitmap.erase(@width - m, 0, m, m)
    @frame.bitmap.erase(0, @height - m, m, m)
    @frame.bitmap.erase(@width - m, @height - m, m, m)
    @frame.bitmap.blt(0, 0, @skin.bitmap, @skin['ul_corner'])
    @frame.bitmap.blt(@width - m, 0, @skin.bitmap, @skin['ur_corner'])
    @frame.bitmap.blt(0, @height - m, @skin.bitmap, @skin['dl_corner'])
    @frame.bitmap.blt(@width - m, @height - m, @skin.bitmap, @skin['dr_corner'])
  end
end

Now you can remove the windowskin and window padding script fixes and replace them entirely with this Window's Rewrite. I'll have to make note of this.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

Hm, is replacing the Window class not kinda inefficient?
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

Can't be any more inefficient than replacing the Tilemap class. :P

The rewrite is nice since it modifies the windows to behave like the XP windows rather than VXA windows; less headaches for users making sure if their windows are not buggy. Plus, we now have more access to the windows themselves--change the wait arrows, move things around, make different window cursors, etc.

I could do a stress test and see how many windows start to lag the game, though I would highly doubt the two would be much different, if at all.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

January 14, 2016, 01:29:21 pm #74 Last Edit: January 14, 2016, 01:30:35 pm by Blizzard
I tried it any within 15 seconds I came across 3 problems.

1. Some text won't show up.
2. The stretching of the cursor has some serious artifacts. I'm pretty sure it's using nearest neighbor rather linear interpolation. Might be VXA's .exe though.
3. It works on the title screen and save-loading screen, but crashes on @frame being nil as soon as the map should load.

*sigh* I'm seriously thinking about just writing my own Window class. I can probably easily scavenge my C++ implementation from ARC. It would probably be faster that trying to debug this. Not that the code is bad. It's decent. It's just that it doesn't work fully which aggravates me.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

Your windows must be super unique and perform functions the Window class never really expected. I mean I've been using this script for years in Advance Wars Engine and have never had a single issue with it, both in XP and XPA.

Maybe Zexion and I can research it some more, but there really isn't much promise without knowing what are triggering these unique errors.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

January 14, 2016, 04:19:19 pm #76 Last Edit: January 14, 2016, 04:29:37 pm by Blizzard
IDK, but I'm 99% sure that not all of the default Window class' functionality have been implemented in that script. Maybe I'm using an initialize call with a viewport argument, because I don't see it supported in this script.

Also, I just noticed panorama doesn't work in XPA. ._.

EDIT: Ah, fuck, I found it. I'm using a @frame variable myself somewhere in a Window class of my own.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

I don't think Windows even have viewports. Looking at Window_Base, there's no reference to a viewport in there either.
Stretching of the cursor appears to be using Bitmap#stretch_blt, which I believe is not that great of a method if I can recall. It doesn't look like it's even used in the default scripts either.
I'll have to look at the outline thing when I get the chance--never really played too much with that one.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Blizzard

January 14, 2016, 04:31:29 pm #78 Last Edit: January 14, 2016, 04:39:34 pm by Blizzard
Definitely more naming conflicts. Though, I'm still having trouble with some of the font rendering.

I'm pretty sure myself that Window doesn't support viewport. But it's been so long since the last time I touched XP that I can't remember some things accurately.

I figured the outline thing out. I had to use out_color for it to work. But it's weird. It works in XP and in my new Windows class, but it won't work in XPA when I use that script. ._. Man, so much stuff.

EDIT: stretch_blt should be the right way to go. The problem is that he didn't do it right. He blitted the whole thing at once which is incorrect. The borders of the cursor image are blit separately and in a thinner manner before blitting the center image.

EDIT: These are the correct formulas.

		int w = hmax(this->cursorRect->width - 4, 0);
int h = hmax(this->cursorRect->height - 4, 0);
this->cursorBitmap->_renderToTexture(0, 0, 2, 2, 0, 0, this->windowskinCursor);
this->cursorBitmap->_renderToTexture(30, 0, 2, 2, w + 2, 0, this->windowskinCursor);
this->cursorBitmap->_renderToTexture(0, 30, 2, 2, 0, h + 2, this->windowskinCursor);
this->cursorBitmap->_renderToTexture(30, 30, 2, 2, w + 2, h + 2, this->windowskinCursor);
if (w > 0)
{
this->cursorBitmap->_renderToTexture(2, 0, 28, 2, 2, 0, w, 2, this->windowskinCursor);
this->cursorBitmap->_renderToTexture(2, 30, 28, 2, 2, h + 2, w, 2, this->windowskinCursor);
}
if (h > 0)
{
this->cursorBitmap->_renderToTexture(0, 2, 2, 28, 0, 2, 2, h, this->windowskinCursor);
this->cursorBitmap->_renderToTexture(30, 2, 2, 28, w + 2, 2, 2, h, this->windowskinCursor);
}
if (w > 0 && h > 0)
{
this->cursorBitmap->_renderToTexture(2, 2, 28, 28, 2, 2, w, h, this->windowskinCursor);
}
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

KK20

January 14, 2016, 04:40:34 pm #79 Last Edit: January 14, 2016, 04:41:56 pm by KK20
From the script:

  def draw_rect
    return if @skin == nil
    if @width > 0 and @height > 0
      self.bitmap = Bitmap.new(@width, @height)
      rect = Rect.new(1, 1, @width - 2, @height - 2)
      self.bitmap.stretch_blt(rect, @skin, @rect['bg'])
      self.bitmap.blt(0, 0, @skin, @rect['upleft'])
      self.bitmap.blt(@width-1, 0, @skin, @rect['upright'])
      self.bitmap.blt(0, @height-1, @skin, @rect['downright'])
      self.bitmap.blt(@width-1, @height-1, @skin, @rect['downleft'])
      rect = Rect.new(1, 0, @width - 2, 1)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_up'])
      rect = Rect.new(0, 1, 1, @height - 2)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_left'])
      rect = Rect.new(1, @height-1, @width - 2, 1)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_down'])
      rect = Rect.new(@width - 1, 1, 1, @height - 2)
      self.bitmap.stretch_blt(rect, @skin, @rect['cursor_right'])
    end
  end

Yeah I can see by what you mean. Just blits a 1 pixel border and then stretches the background.

And yeah, the Plane support has been know for a couple years already. Did I not put that in the XPA Tilemap?
Oh I did. And I see the edit :P

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!