[RGD] DirectX implementation of RGSS3

Archeia

Level 99 Demi-fiend
Staff member
Developer
Joined
Mar 1, 2012
Messages
15,168
Reaction score
15,508
First Language
Filipino
Primarily Uses
RMMZ

BCj

Veteran
Veteran
Joined
Jun 19, 2014
Messages
1,733
Reaction score
931
First Language
Dutch
Primarily Uses
N/A
@BCj I tried Calibri on my own project. Everything works fine. I believe both of your problems have something to do with Lunar Engine, or the incompatibility between RGD and Lunar Engine somewhere.
Please send me the dll file then I'll ask Fux2 to handle it, which may take a couple of days.
Thank you for the feedback and screenshots!
I found out what was causing the error with the text. It was this script:


Code:
# Text Cache
# by Mithran
# posted at forums.rpgmakerweb.com

# Instructions
%Q(
This script is a workaround for the Bitmap#draw_text issues in RPGMaker VX Ace.

By default, there are several errors with Bitmap#draw_text in Ace.

1.  Text shrinking algorithm is overzealous.  Text drawn to a rect given by
    its own text_size is reduced in size.  This is both counterintuitive, and not
    the way it worked in previous versions (VX).
 
2.  Text drawn to any rect wider than approx 640 pixels wraps around to the
    beginning of the line, overwriting previous text.  This also causes center
    and right alignments to fail.  This is both unnecessary and not how it worked
    in VX.
  
3.  Text drawn character by character with non true-type fonts has awkward spacing.
    In addition, the text_size of a string of characters is not the same as the
    sum of the text_size of each character.
    This existed even in VX.
  
4.  The first character of a Bitmap#draw_text command for certain letters on
    certain fonts is not drawn correctly.  Since message window draws character
    by character, this can become a major issue. (example: Verdana 20 pt font)
  
These errors can be demonstrated using my text draw debugger:
http://pastebin.com/p55ukZP2
  
What this script does:

1.  Adds 2 pixels to any draw_text width, so text can be intuitively drawn to its
    own text_size rect. Offsets x coordinate where appropriate.
    If SIMPLE_FIX is set to true, only this fix will be enabled.
  
2.  Adds a text cache.  Instead of drawing text directly when called, a unique
    bitmap is created for any potential text draw with buffers, drawn with extra
    space around it.  The character is then copied whenever a text draw is
    attempted.
  
    Text Caching can be turned off by setting SIMPLE_FIX to true.
  
    Text Caching also has the following features:
    - Much faster processing than the original Bitmap#draw_text.
      Trades a small amount of memory to accomodate faster processing speed.
      The first time any letter is drawn takes approximately 3-4 times as long,
      subsquently, any time this same letter and font is drawn it is upwards of
      twice as fast.  The longer the string drawn, the bigger the difference.
    - Accounts for a 3-length string when checking the size.  This makes single
      characters drawn look more natural for the offending fonts.
    Does not work with:
    - Reduced size text.
      If text is squeezed due to not being given enough room to draw, text caching
      is bypassed in favor of the original method.  This is due to the text
      squeezing algorithm reducing each character by a variable amount that can
      not be determined with text_size.  Manually stretching or aligning this
      "squeezed" text looks completely awful, so for now, this will have to
      stay like this.
      The exception to this is if the text has "just enough" room to draw,
      it will be given the two extra pixels rather than squeezing it.
    - If text extends beyond MAX_DRAW_WIDTH, text caching will be forced.
      This disables the "squeeze" effect.  Using the default method means the text
      would draw over itself anyway, so this is the lesser of two evils.
    
Changelog:

v 1.01
  Fixed crash error when using F12 to reset. (Thanks Archiea_Nessiah)

v 1.0
Official release.
)

#
 
class Bitmap
  TEXT_TOP_BUFFER = 2
  TEXT_SIDE_BUFFER = 8 # buffer in pixels to draw text away from
  # the edge of the bitmap, to prevent certain characters from being cut off
  SIMPLE_FIX = false # just adds the two pixels to prevent unnecessary squeeze
  MAX_TEXT_DRAW_WIDTH = 640 # tests have shown the draw fails at around 640px
  # if nil, no max width
  NO_FIX = false # completely disables the fix, for testing comparison
 
 
  alias draw_text_vxa draw_text
  def draw_text(*args)
    return draw_text_vxa(*args) if NO_FIX
    if args[0].is_a?(Rect)
      rect = args[0]
      x, y, width, height = rect.x, rect.y, rect.width, rect.height
      text = args[1].to_s.clone || ""
      align = args[2] || 0
    else
      x, y, width, height = *args[0..3]
      text = args[4].to_s.clone || ""
      align = args[5] || 0
    end
    text_rect = self.text_size(text)
    text_width = text_rect.width
    text_height = text_rect.height
    squeeze = text_width > width
    if SIMPLE_FIX or (squeeze and (MAX_TEXT_DRAW_WIDTH and width <= MAX_TEXT_DRAW_WIDTH))
      x -= align
      # shift one pixels to the left if centering
      # two if right right justified
      # to offset the extra width given
      return draw_text_vxa(x, y, width + 2, height, text, align)
    else
      # TextCache.canvas(font) # passing the font slows this down extremly, changed it to later
      fontkey = self.font.to_a
      case align
      when 1; x += (width - text_width) / 2
      when 2; x += width - text_width
      end
      y += (height - text_height) / 2 # horizontal center
      buf = -TEXT_SIDE_BUFFER
      text.each_char { |char|
        letter = TextCache.letters(fontkey, char)
        draw_text_vxa(x + buf, y, letter.rect.width + 2, letter.height, char) if SIMPLE_FIX
        # swap with original method for debugging and simple fix
        self.blt(x + buf, y, letter, letter.rect) unless SIMPLE_FIX
        buf += letter.rect.width - TEXT_SIDE_BUFFER * 2
      }   
    end
  end
end

module TextCache
  BUFFER_DRAW = 300 # for drawing characters, to make sure there is enough room
 
  def self.canvas(font = nil)
    @canvas = Bitmap.new(32, 32) if @canvas.nil? || @canvas.disposed?
    #@canvas.font = font if font and font != @canvas.font
    @canvas
  end
 
  def self.letters(font, char)
    @cache ||= {}
    key = font + [char]
    if include?(key)
      return @cache[key]
    elsif char.empty?
      return empty_bitmap
    else
      return new_letter(font, char)
    end
  end
 
  def self.empty_bitmap # not used, added for completness in case the cache is accessed directly
    @cache[:empty] = Bitmap.new(32, 32) unless include?(:empty)
    @cache[:empty]
  end
 
  def self.new_letter(fontary, char)
    font = create_font(fontary)
    # get the font
    canvas.font = font
    rect = canvas.text_size(char * 3)
    # get size of character between two other characters (for better kerning)
    b = Bitmap.new((rect.width / 3) + Bitmap::TEXT_SIDE_BUFFER * 2, rect.height)
    # create bitmap just big enough for one character
    b.font = font
    # get the font
    b.draw_text_vxa(rect.x - b.text_size(" ").width + Bitmap::TEXT_SIDE_BUFFER, rect.y - Bitmap::TEXT_TOP_BUFFER, BUFFER_DRAW, rect.height + Bitmap::TEXT_TOP_BUFFER * 2, " #{char} ", 0)
    # draw blank spaces before and after character, fix for cutting off the
    # first pixel using draw_text
    key = fontary + [char]
    @cache[key] = b 
  end
 
  def self.create_font(fontary)
    font = Font.new(*fontary[0..1])
    font.bold = fontary[2]
    font.italic = fontary[3]
    font.outline = fontary[4]
    font.shadow = fontary[5]
    font.color.set(*fontary[6..9])
    font.out_color.set(*fontary[10..13])
    font
  end

 
  def self.include?(key)
    @cache[key] && !@cache[key].disposed?
  end

  def self.clear
    @cache ||= {}
    @cache.clear
    GC.start
  end
 
end



class Font
  # font's instance variables are not reflective, so this has to be defined explicitly
  def to_a
    [name, size, bold, italic, outline, shadow, color.red, color.green, color.blue, color.alpha, out_color.red, out_color.green, out_color.blue, out_color.alpha]
  end
 
end
Since your game.exe has a built-in text cache (right? that's what I understood) I guess this should be deleted.

As for the graphical issue, I'll send you a pm :)

Edit: I disabled the script Archeia mentioned (KGC bitmap extender?) but, my screen still turns yellow.
 

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
The problem of incorrect font has been fixed (which also worked in BCj's environment) and will be published in next update.
 

dsiver144

Peaceful Days Dev
Veteran
Joined
Sep 19, 2013
Messages
265
Reaction score
827
First Language
Vietnamese
Primarily Uses
RMVXA
In my game, I use a lot of blt function to transfer image from small bitmaps to a larger bitmap. Sometime it works fine. But sometime it doesn't. :D
 

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
In my game, I use a lot of blt function to transfer image from small bitmaps to a larger bitmap. Sometime it works fine. But sometime it doesn't. :D
The address of bitmap is already different from RGSS I think. Another difference is that RGSS saves bitmap from bottom line to top line while RGD saves from top to bottom.
If you need high performance bitmap operators, I suggest using shaders in Sprite.
 

dsiver144

Peaceful Days Dev
Veteran
Joined
Sep 19, 2013
Messages
265
Reaction score
827
First Language
Vietnamese
Primarily Uses
RMVXA
Thanks for answering. Gonna do some more expriment on this. :D
You guys did a really good job there!
 

BCj

Veteran
Veteran
Joined
Jun 19, 2014
Messages
1,733
Reaction score
931
First Language
Dutch
Primarily Uses
N/A
How do you launch fullscreen now? I noticed if "Fullscreen" is checked in the editor it won't launch fullscreen. And F1 won't work anymore, as I read in your document.
 

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
How do you launch fullscreen now? I noticed if "Fullscreen" is checked in the editor it won't launch fullscreen. And F1 won't work anymore, as I read in your document.
Sorry we forgot implementing full screen launching from editor. You may still press Alt+Enter to go fullscreen.
And the Enter button in Alt+Enter triggers Input module at present. We are going to fix these issues soon.
We believe F1 option menu is not fit for most games, so we did not implement it. A custom Options menu would be much better.
 

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,275
Reaction score
1,438
First Language
English
Primarily Uses
RMXP
This looks absolutely amazing.
Great job! <3
 

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
How do you launch fullscreen now? I noticed if "Fullscreen" is checked in the editor it won't launch fullscreen. And F1 won't work anymore, as I read in your document.
I'm sorry that we are not going to implement "launch in fullscreen" from editor. The function of fullscreen is implemented by changing some values in registry in RMVXAce editor and Game.exe, which is not friendly to game players who do not have RMVXAce installed.
You may use Graphics.toggle_fullscreen and switch into fullscreen mode in your game.
 

BCj

Veteran
Veteran
Joined
Jun 19, 2014
Messages
1,733
Reaction score
931
First Language
Dutch
Primarily Uses
N/A
I'm sorry that we are not going to implement "launch in fullscreen" from editor. The function of fullscreen is implemented by changing some values in registry in RMVXAce editor and Game.exe, which is not friendly to game players who do not have RMVXAce installed.
You may use Graphics.toggle_fullscreen and switch into fullscreen mode in your game.
And how would that work? E.g. if I have an options settings that allows the player to select fullscreen or not, how would I activate it, if they press "yes"?
 

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
And how would that work? E.g. if I have an options settings that allows the player to select fullscreen or not, how would I activate it, if they press "yes"?
You may use a variable to store graphic fullscreen state. If it is true and becomes false after the setting, then call "Graphics.toggle_screen". You can also store the variable in file (using Marshal.dump or existing long-lasting variable scripts) if you want your settings keep the same after the game is restarted.
 

dsiver144

Peaceful Days Dev
Veteran
Joined
Sep 19, 2013
Messages
265
Reaction score
827
First Language
Vietnamese
Primarily Uses
RMVXA
I wonder if we can upscale game contents to a specific ratio? Like double window size with its contents but not the game resolution. :D
 

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
Update: Jun 7, 2018 – Version 1.1
  • Added callback on window getting focus, losing focus and closing.
  • Added bitmap on Geometry.
  • Added resizing window function.
  • Fixed lots of bugs.

All the recorded problems from BCj and dsiver144 have been fixed.
 
Last edited:

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
Update: Jul 1, 2018 – Version 1.1.1
  • Added Graphics.resize_window to resize game window directly.
  • Fixed some bugs.
 

Kvothe

The Bloodness
Veteran
Joined
Jan 21, 2014
Messages
149
Reaction score
557
First Language
Brazil
Primarily Uses
N/A
Some question: this cannot be converted to RMXP? I mean, I know that it was created by ACE, but who knows? hehe
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
598
First Language
Italian
Primarily Uses
RMVXA
First of all thank you for the effort, I really appreciate something like this. That said I have a question: do we have to manually resize all of our standard Viewports when increasing screen size?

EDIT: by manually I mean modifying the initialize method for Viewport class, I don't plan on modifying them one by one.
 
Last edited:

invwindy

Ice Fairy
Veteran
Joined
Apr 9, 2016
Messages
91
Reaction score
101
First Language
Chinese
Primarily Uses
RMVXA
First of all thank you for the effort, I really appreciate something like this. That said I have a question: do we have to manually resize all of our standard Viewports when increasing screen size?

EDIT: by manually I mean modifying the initialize method for Viewport class, I don't plan on modifying them one by one.
I'm afraid the viewport size in RGD is set same as current screen size on initialization. And there is no Viewport#resize at present. You may exit and enter the scene again then call Viewport.new again with new resolution.
 

Heirukichi

Veteran
Veteran
Joined
Sep 24, 2015
Messages
1,421
Reaction score
598
First Language
Italian
Primarily Uses
RMVXA
@invwindy thank you for the info. If creating a new viewport is enough then this should fix it for the whole game since it resizes graphics before everything else runs.
Code:
module SceneManager
 
  class << SceneManager
 
    alias hfsc_run_old  run
    def run
      Graphics.resize_screen(1024, 768) # your screen resolution goes here
      Graphics.toggle_fullscreen
      hfsc_run_old
    end
 
  end
 
end
I am posting it here so anyone who needs it can use it.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

rux
MUCLSES!!! :epicface: :epicface:
If you're reviewing someone else's game, don't focus only on the negative and criticize them. Use positive constructive feedback. As game developers, we need to empower one another; not put each other down.
just posted a song I made for my game a while back... I sampled the HEY from Earthworm Jim's Snot a problem levels lol...
Based on this screenshot alone, which one would you sell, and which to equip?
Some random sketch-letons.

Forum statistics

Threads
107,494
Messages
1,030,071
Members
139,622
Latest member
coolguy69lol
Top