Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Transition

As some of you might know, the transitions of Graphics.transition only support 640x480
So it won't work with a script which let's you change the resolution (like the one I am working on x)
I already tried to rewrite it and it acutally works but it needs about 15 seconds with a 640x480 screen and duration of 8 (the heigher the duration the longer it takes)
And if a PC is a bit worse than my one it may give a "Script is hanging"-error
So I need one of three solutions:
1. Someone writes a library and the corresponding ruby code
2. Someone already did rewrite Graphics.freeze and Graphics.transition
3. Someone gives me a good idea how I could do this
 
Neo-Bahamut":1xn4gaoz said:
As some of you might know, the transitions of Graphics.transition only support 640x480
So it won't work with a script which let's you change the resolution (like the one I am working on x)
I already tried to rewrite it and it acutally works but it needs about 15 seconds with a 640x480 screen and duration of 8 (the heigher the duration the longer it takes)
And if a PC is a bit worse than my one it may give a "Script is hanging"-error
So I need one of three solutions:
1. Someone writes a library and the corresponding ruby code
2. Someone already did rewrite Graphics.freeze and Graphics.transition
3. Someone gives me a good idea how I could do this

I don't have a Graphics.freeze code, but I can tell you what it does. It appears to take a screenshot and display it over everything else, then transition that screenshot. As to a solution, look around for screenshot code, and then try this little .dll file I was working with a few months ago. It certainly isn't perfect, as it doesn't have vague, but it works better than nothing.

You can find the .dll file here, although there are no guarantees about satisfaction. It is a WIP that may never be finished. Anyway, to use it, you have to make the following Win32API calls:

Code:
class Bitmap

  def update_transition(other_bitmap, frames)

    if @shade == nil

      @shade = 0

    end

    @previous_shade = @shade

    @shade = (@shade * (frames - 1) + 255) / frames

    raise RGSSError.new("Disposed bitmap") if disposed?

    func=Win32API.new("transition.dll","Transition","llll","v")

    func.call(self.__id__, other_bitmap.__id__, @previous_shade, @shade)

  end

end

just mess around with the code, by calling it from a bitmap. I can't recall which bitmap is actually being modified, so you might want to experiment. ALso, you'll want to make sure to call this once a frame, with the correct number of remaining frames included in the frames variable. If you want the original code for the .dll file, I can go ahead and post it, as it's not really and state secret or anything.
 
trebor777":1b3vjnmt said:
I'm quite curious on the process behind the transition method :p
How does it work?

It actually edits the image. Here's the source code. (Please note that this uses a modified version of some code found on this forum)

C++:
<span style="color: #339900;">#include <stdio.h>

<span style="color: #339900;">#include <stdlib.h>

<span style="color: #339900;">#include <string.h>

<span style="color: #339900;">#include <windows.h>

<span style="color: #339900;">#include <ctype.h>

<span style="color: #339900;">#include <math.h>

 

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) {

    switch (ul_reason_for_call) {

        case DLL_PROCESS_ATTACH:

        case DLL_THREAD_ATTACH:

        case DLL_THREAD_DETACH:

        case DLL_PROCESS_DETACH:

        break;

    }

    return true;

}

 

typedef struct {

    DWORD flags;

    DWORD klass;

    void (*dmark) (void*);

    void (*dfree) (void*);

    double *data; //red is index 1, green is index 2, blue 3, alpha 4

} RGSSCOLOR;

 

typedef struct{

    DWORD unk1;

    DWORD unk2;

    BITMAPINFOHEADER *infoheader;

    RGBQUAD *firstRow;

    RGBQUAD *lastRow;

} RGSSBMINFO;

 

typedef struct{

    DWORD unk1;

    DWORD unk2;

    RGSSBMINFO *bminfo;

} BITMAPSTRUCT;

 

typedef struct{

    DWORD flags;

    DWORD klass;

    void (*dmark) (void*);

    void (*dfree) (void*);

    BITMAPSTRUCT *bm;

} RGSSBITMAP;

 

<span style="color: #339900;">#define ASSERT(x) if(!x){DebugOut("Failed: %s: %d", #x, __LINE__);}

  

 

BOOL Bitmap_Recolor(long object1, long object2, int luminosity){

    DWORD tmp = <span style="color: #0000dd;">0;

    RGSSBMINFO *bitmap1 = ((RGSSBITMAP*) (object1<<<span style="color: #0000dd;">1)) -> bm -> bminfo;

    RGSSBMINFO *bitmap2 = ((RGSSBITMAP*) (object2<<<span style="color: #0000dd;">1)) -> bm -> bminfo;

    DWORD rowsize;

    DWORD width, height;

    LPBYTE row1, row2;

    long xStart = <span style="color: #0000dd;">0;

    long yStart = <span style="color: #0000dd;">0;

    long x, y;

    int red, green, blue; //Color of current pixel

    if(!bitmap1 || !bitmap2) {

        return false;

    }

    width = bitmap1 -> infoheader -> biWidth;

    height = bitmap1 -> infoheader -> biHeight;

    rowsize = width * <span style="color: #0000dd;">4;

    if((width == xStart) || (height == yStart)) return TRUE;

    row1 = (LPBYTE)(bitmap1 -> firstRow - yStart * rowsize + xStart * <span style="color: #0000dd;">4);

    row2 = (LPBYTE)(bitmap2 -> firstRow - yStart * rowsize + xStart * <span style="color: #0000dd;">4);

    for ( y = yStart; y < height; y++) {

        LPBYTE thisrow1 = row1;

        LPBYTE thisrow2 = row2;

        for ( x = xStart; x < width; x++) {

            red = thisrow2[<span style="color: #0000dd;">0];

            green = thisrow2[<span style="color: #0000dd;">1];

            blue = thisrow2[<span style="color: #0000dd;">2];

            if ((red <= luminosity) && (green <= luminosity) && (blue <= luminosity)) {

                thisrow1[<span style="color: #0000dd;">0] = <span style="color: #0000dd;">0;

                thisrow1[<span style="color: #0000dd;">1] = <span style="color: #0000dd;">0;

                thisrow1[<span style="color: #0000dd;">2] = <span style="color: #0000dd;">0;

                thisrow1[<span style="color: #0000dd;">3] = <span style="color: #0000dd;">0;

            }

            thisrow1 += <span style="color: #0000dd;">4;

            thisrow2 += <span style="color: #0000dd;">4;

        }

        row1 -= rowsize;

        row2 -= rowsize;

    }

    return true;

}

 

extern <span style="color: #666666;">"C" _declspec (dllexport) BOOL Transition(long object1, long object2, int prevshade, int shade){

    int luminosity = prevshade;

    while (luminosity <= shade) {

        Bitmap_Recolor(object1, object2, luminosity);

        luminosity += <span style="color: #0000dd;">1;

    }

    return true;

}
 
@ Glitchfinder: Ruby is the only programming language I am working with (well, I'm learning Python now) so an unfinished library won't help me and I need vague because it makes the transitions smoooooooth :3
But thanks anyway

@ trebor777: Here is the unfinished version of my try because I deleted the newer one in frustration xD
It doesn't really work but if you understand the code you will see the process (I am pretty sure this is the way it works)

Code:
#=============================================================================

# ** Graphics

#-----------------------------------------------------------------------------

#  Rewrites Graphics.freeze and Graphics.transition

#=============================================================================

module Graphics

  

  # If the Transition is smaller than the Screen...

  #   0: Do the rest like it was filled with black

  #   1: Copy the Bitmap abreast

  #   2: Stretch the Bitmap

  Transition_Scale_Method = 0

  

  @_freezed_sprite = Sprite.new

  @_freezed_sprite.z = 1073741823

  

  #--------------------------------------------------------------------------

  # * Freezes the Screen

  #--------------------------------------------------------------------------

  def self.freeze

    # Make Screenshot

    Screenshot.shot("screenshot")

    screen = Bitmap.new("screenshot.png")

    File.delete("screenshot.png")

    @_freezed_sprite.bitmap = screen

  end

  

  #--------------------------------------------------------------------------

  # * Performs a transition

  #     duration: The duration in frames.

  #     filename: The filename of the transition.

  #     vague: The softness of the transition.

  #--------------------------------------------------------------------------

  def self.transition(duration = 8, filename = "", vague = 40)

    self.prepare_transition(duration, filename, vague)

    Graphics.update

    # Do the Transition

    for frame in 0...duration

      @_freezed_sprite.bitmap = @_next_transition[frame]

      Graphics.update

    end

    # Dispose everything and start GC

    @_freezed_sprite.bitmap = Bitmap.new(1, 1)

    bitmap, @_next_transition, hash = 0, 0, 0, 0

    GC.start

  end

  

  private

  #--------------------------------------------------------------------------

  # * Prepares a Transition

  #     duration: The duration in frames.

  #     filename: The filename of the transition.

  #     vague: The softness of the transition.

  #--------------------------------------------------------------------------

  def self.prepare_transition(duration, filename, vague)

    time = Time.now

    # Make Transition-Bitmap

    bitmap = self.transition_bitmap(filename)

    # Calculate pixels

    pixels = self.transition_order(bitmap, duration)

    # Pack pixels so its size is equal to duration

    array = Array.new(duration, [])

    part = (255.0/duration).ceil

    for n in 1..256

      dur = (n.to_f/part).ceil - 1

      array[dur] = array[dur].concat(pixels[n-1])

    end

    Graphics.update

    @_next_transition = self.transition_create_bitmaps(array, duration, vague)

  end

  

  #--------------------------------------------------------------------------

  # * Makes the Transition-Bitmaps. 

  # (this methods needs a loooong time => sometimes 'Script is hanging')

  #     array: The Array which holds the pixel-data.

  #     duration: The duration in frames.

  #     vague: The softness of the transition.

  #--------------------------------------------------------------------------

  def self.transition_create_bitmaps(array, duration, vague)

    bitmaps = Array.new(duration) {|n| @_freezed_sprite.bitmap.dup}

    # Loop through frames

    for frame in 0...duration

      # Create vague-hash

      hash = {}

      for n in 0...vague

        break if (frame-n) < 0

        k = vague < 1 ? 0 : n*255/vague

        hash[k] = array[frame]

      end

      # Create Bitmap

      bmp = bitmaps[frame]

      for opacity in hash.keys

        Graphics.update

        for pix in hash[opacity]

          x, y = pix[0], pix[1]

          color = bmp.get_pixel(x, y)

          bmp.set_pixel(x, y, Color.new(color.red, color.green, color.blue, opacity))

        end

      end

    end

    bitmaps

  end

  

  #--------------------------------------------------------------------------

  # * Returns the finished Transition-Bitmap

  #     filename: The filename of the image.

  #--------------------------------------------------------------------------

  def self.transition_bitmap(filename)

    # Get width and height of the RGSS-Player

    if method_defined?(:width) && method_defined?(:height)

      w, h = self.width, self.height

    else

      w, h = 640, 480

    end

    # Create Transition-Bitmap

    if filename == ""

      bitmap = Bitmap.new(w, h)

      bitmap.fill_rect(bitmap.rect, Color.new(0, 0, 0))

    else

      bitmap = RPG::Cache.transition(filename)

    end

    # If the Bitmap is smaller than the screen

    if bitmap.width < w or bitmap.height < h

      new = Bitmap.new(w, h)

      case Transition_Scale_Method

      when 0

        new.fill_rect(new.rect, Color.new(0, 0, 0))

        new.fill_rect(bitmap.rect, Color.new(0, 0, 0, 0))

        new.blt(0, 0, bitmap, bitmap.rect)

      when 1

        tw = (w.to_f/bitmap.width).ceil

        th = (h.to_f/bitmap.height).ceil

        for ox in 0...tw

          for oy in 0...th

            x, y = ox*bitmap.width, oy*bitmap.height

            new.blt(x, y, bitmap, bitmap.rect)

          end

        end

      when 2

        new.stretch_blt(new.rect, bitmap, bitmap.rect)

      end

      bitmap = new

    end

    bitmap

  end

  

  #--------------------------------------------------------------------------

  # * Returns an Array with the pixel-order

  #     bitmap: The Transition as a Bitmap

  #     duration: Duration of the Transition

  #--------------------------------------------------------------------------

  def self.transition_order(bitmap, duration)

    array = Array.new(256) {|n| Array.new}

    # Loop through each pixel

    for x in 0...bitmap.width

      for y in 0...bitmap.height

        # Get color

        c = bitmap.get_pixel(x, y)

        # Calculate average (grayscale it)

        av = Math.average(c.red, c.green, c.blue).round

        # Add the coordinates to array

        array[av] << [x, y]

      end

    end

    array

  end

  

end
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top