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.

Bitmap Effects Using A Fast Way to Get Bitmap Data

poccil

Sponsor

This document explains a fast way to get the data from an RGSS bitmap object,
which I have discovered.

Internally, RGSS bitmaps are stored as Windows bitmap data.
Using a Win32 DLL, it is possible to retrieve this data's internal
structure with the help of a little known trick using the Ruby object's ID:

Ruby code follows illustrating this technique with a hypothetical DLL "mydll.dll"
and a hypothetical function "MyFunction".

Code:
 

o=Bitmap.new(10,10)

function=Win32API.new("mydll.dll","MyFunction","l","")

# Pass the object's ID to the function

function.call(o.__id__)

 

Having retrieved the object's ID, the DLL function can shift the ID left by 1 to get
a pointer to the object's internal data structure.  C code follows illustrating
the technique.

Code:
 

void __declspec(dllexport) __stdcall MyFunction(unsigned long object){

 RGSSBITMAP *data=(RGSSBITMAP *)(object<<1);

// Process data pointer here...

}

 

In this case, the ID for a bitmap refers to the Ruby structure for
arbitrary data.  This structure points to a bitmap structure, which in
turn points to the actual information on the bitmap.  All three structures
are defined below. (The code below is in C.)

Code:
 

#include <windows.h>

 

// Actual bitmap info

typedef struct{

 DWORD unk1;

 DWORD unk2;

 BITMAPINFOHEADER *infoheader;

 // First row of the bitmap, rows

 // are stored in descending order

 RGBQUAD *firstRow;

 // Last row of the bitmap

 RGBQUAD *lastRow;

} RGSSBMINFO;

 

// Bitmap data

typedef struct{

 DWORD unk1;

 DWORD unk2;

 RGSSBMINFO *bminfo;

} BITMAPSTRUCT;

 

// Ruby data structure

typedef struct{

 DWORD flags;

 DWORD klass;

 void (*dmark)(void*);

 void (*dfree)(void*);

 BITMAPSTRUCT *bm;

} RGSSBITMAP;

 

Using this knowledge, the DLL function can process the bitmap however it
wants.  For example, it can save the bitmap, retrieve a whole row of it,
perform a complex effect on it, and so on.

I'm not sure whether this thread is appropriate here, but
this information may be known by no one until now.

A demo for the bitmap effects used to be here, but the link is now broken.
 

poccil

Sponsor

I have updated the bitmap effects demo today with some more effects, including all new effects from RGSS 2's Bitmap class.
 

khmp

Sponsor

I know this sounds forward of me but can I have your babies? I had absolutely no idea left shifting the __id__ by 1 reveals the pointer to a Ruby object's data. I assume this is true for all Ruby objects then as well not just bitmaps? Very cool. Did you stumble upon that by yourself or happen to see it elsewhere? Modifying the bitmap data directly through C/C++ code like this was the very first question I had when I came here.
 

poccil

Sponsor

Thanks for asking.  I recently discovered that possibility by myself when I posted this topic.  I encourage users to try this technique.
 
This is one of the greatest ideas I have ever heard for enhancing RMXP. Great discovery!
This can be revolutionary for RMXP, and maybe can be useful for anothers objects types.
 

xpace

Member

Wow! Very cool discovery!  :thumb:

I have one question:

Is the framerate of the bitmap demo being limited by a software limitation (such as RGSS)? Or did you put some sort of throttle in so it would only move the bitmaps slowly?

C/C++ code usually runs very fast. If that is as fast as it can display the bitmaps, then I think the usefulness of this technique might also be limited...  :sad:
 

poccil

Sponsor

No, it's just that the operation demonstrated, a radial blur, is a relatively time-intensive operation
compared with other bitmap effects, such as applying a gradient fill.  It would be considerably slower
using RGSS's set_pixel and get_pixel methods.
 

poccil

Sponsor

What the demo does is modify the bitmaps passed to it by their object IDs.  (In RGSS, graphics are drawn using sprites, which each hold bitmap objects.)  The technique doesn't need to know the RGSS player's window handle in order to do so.  The RGSS player then draws the modified bitmaps in the usual way.
 
From what i could see, he just found a way to take out data from the interpreter and use it within external methods/functions from inside the interpterer itself. This way, he took bitmaps' data and used an external tool to modify it. Maybe it´d be possible to modify things with a managed DLL, but you´d need to describe the bitmap data in the language you use in such way it´d fit perfectly in the way it´s described in the C source code provided by poccil. If not, make some kind of interface that works byte-by-byte. But either way, i wonder if it´d be possible to actually call managed language's DLL calls from inside the RGSS with Win32API, as i´m only aware of that C/C++ are supported.

To compile it, i guess any regular compile should do. Borland, VC, Mingw... I personally recommend getting the VC compiler, as it generates smaller DLLs compared to any other compilers. If you don´t want to use it, Mingw is a good option too.

BTW that ID thing discovery was brilliant lol i wonder where you got that info :D
BTW2, i wonder why shifting the pointer by one bit anyway... What´d be the advantage of making it? Randomizing IDs?
BTW3, i see some GDI structs there. If they´re not meant to be only binary-compatible with some other data struct, this could explain why RMXP games are rather slow for such small work :)
 
I - LOVE - YOU

lol really, I'm amazed. I've tried so many times to do something like that but RGSS was far too slow. If I can do a masking effect with that, this script is going straight into my FFVI SDK! (Along with your tilemap script ;))

One question: Is it possible for me to add custom effects without having to code them in C? If no then I guess it's time for me to learn C.

Once again, good work poccil!

Take care!
-Dargor
 

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