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.

Custom Game.exe Source Code

Status
Not open for further replies.
@Nuri Yuri
When I was saying Ruby API I didn't mean using it from RGSS (btw it's not possible to load a mingw/gcc compiled .so library with MSVC compiled Ruby. Took me a while to learn that one. :/). I meant using it directly from Game.exe (i.e. the same thing you just wrote).

---

It might be useful to know that there is a workaround to loading ruby extensions with embedded ruby, it's just that they have to be loaded statically (which also means a lot of fiddling with ruby code). I currently can load both DL (had to change the code a little) and Zlib extensions statically (but not Socket extension though, but I've coded my own network interaction, I'm not giving up though xD). Just be sure to use extern "C" { } to specify the call to Init_extname() while in C++.
 
Nuri Yuri":3lzqapi4 said:
The RGSS and Ruby functions are programmed in C/C++ so to make ruby functions work, the rb_define_method/class/module/etc... function should be called somewhere in the RGSS DLL.

For the functions like ruby_xfree, ruby_xmalloc or the functions like rb_gv_get that are called nowhere, I just watch something that looks like the assembly version of them.
To test them :
C:
<div class="c" id="{CB}" style="font-family: monospace;"><ol><span style="color: #993333;">typedef VALUE (*frb_gv_set)(<span style="color: #993333;">char* name,VALUE* val);

//(char* name,VALUE* val);

<span style="color: #339933;">#define rb_gv_set(name,val) ((frb_gv_set)0x100B7300)(name,val)
C++:
    //Validation du mode de fonctionnement du RGSS

    if(wcscmp(lpCmdLine, TEXT(<span style="color: #666666;">"btest")) == <span style="color: #0000dd;">0)

    {BattleTest=<span style="color: #0000dd;">2;}

    rb_gv_set(<span style="color: #666666;">"BTEST",&BattleTest);
I started to search function's pointers in RGSS301 :
Code:
[url=http://www.opensource.apple.com/source/ruby/ruby-75/ruby/variable.c]http://www.opensource.apple.com/source/ ... variable.c[/url]

[url=http://rxr.whitequark.org/mri/source/ext/socket/?v=1.8.7-p370]http://rxr.whitequark.org/mri/source/ex ... 1.8.7-p370[/url]

optlink

 

//Ruby

rb_warning 

rb_warn  //rb_warn("no super class for `%s', Object assumed", name);

rb_raise 

rb_raise2 //rb_raise(rb_eTypeError, "can't make subclass of Class");

rb_name_error  //rb_name_error(id, "%s is already defined", name)

rb_to_id 

global_id 

rb_global_entry 

rb_intern 

rb_intern2 100483E0 //rb_intern2("str",size)

rb_id2name 

rb_check_type 

rb_secure 

rb_alias 

rb_attr 

rb_fatal 

rb_block_given_p 

//rb_need_block 

LONG2NUM 

rb_yield 

rb_equal 

rb_check_type_string 

rb_class_new_instance 

rb_class_superclass 

rb_define_alloc_func 10032E20

rb_undef_alloc_func 100316A0

rb_data_object_alloc 

rb_obj_alloc 

rb_obj_call_init 

//rb_add_method 

str_new //ATTENTION METHODE D4APPEL DIFFERENTE ! __fastcall ? Nop, c'est pas du fastcall c'est de l'optimisation de gros bourrin.

rb_str_new //ATTENTION METHODE D4APPEL DIFFERENTE !

rb_str_new2 //ATTENTION METHODE D4APPEL DIFFERENTE !

ary_new 

rb_ary_new //???

rb_ary_new2 

rb_ary_new3 

rb_ary_new4 

---

 

//

rgss_print 

rgss_p 

//rgss_init 

 

 

//Eval

rb_f_eval 

eval 

rb_eval_string 

---

 

<!BASIC RUBY FUNC>

//String

rb_str_cmp_m  1

rb_str_equal  1

rb_str_hash_m  0

rb_str_casecmp  1

rb_str_plus  1

rb_str_times  1

rb_str_format_m  1

rb_str_aref_m  -1

rb_str_aset_m  -1

rb_str_insert  2

rb_str_length  0

rb_str_empty  0

rb_str_match  1

rb_str_match_m  1

rb_str_succ  0

rb_str_succ_bang  0

rb_str_upto_m  -1

rb_str_index_m  -1

rb_str_rindex_m  -1

rb_str_replace  1

rb_str_to_i  -1

rb_str_to_f  0

rb_str_to_s  0

rb_str_inspect  0

rb_str_dump  0

rb_str_upcase  0

rb_str_downcase  0

rb_str_capitalize  0

rb_str_swapcase  0

rb_str_upcase_bang  0

rb_str_downcase_bang  0

rb_str_capitalize_bang  0

rb_str_swapcase_bang  0

rb_str_hex  0

rb_str_oct  0

rb_str_split_m  -1

rb_str_reverse  0

rb_str_reverse_bang  0

rb_str_concat  1

rb_str_crypt  1

rb_str_intern  0

rb_str_include  1

rb_str_scan  1

rb_str_ljust  -1

rb_str_rjust  -1

rb_str_center  -1

rb_str_sub  -1

rb_str_gsub  -1

rb_str_chop  0

rb_str_chomp  -1

rb_str_strip  0

rb_str_lstrip  0

rb_str_rstrip  0

rb_str_sub_bang  -1

rb_str_gsub_bang  -1

rb_str_chop_bang  0

rb_str_chomp_bang  -1

rb_str_strip_bang  0

rb_str_lstrip_bang  0

rb_str_rstrip_bang  0

rb_str_tr  2

rb_str_tr_s  2

rb_str_delete  -1

rb_str_squeeze  -1

rb_str_count  -1

rb_str_tr_bang  2

rb_str_tr_s_bang  2

rb_str_delete_bang  -1

rb_str_squeeze_bang  -1

rb_str_each_line  -1

 

 

---

 

//Array 

rb_ary_aref  -1

rb_ary_fetch  -1

rb_ary_index  -1

rb_ary_rindex  -1

rb_ary_aset  -1

rb_ary_insert  -1

rb_ary_each_index  0

rb_ary_reverse_each  0

rb_ary_length  0

rb_ary_empty_p  0

//rb_ary_reverse 

rb_ary_reverse_bang  0

rb_ary_reverse_m  0

rb_ary_transpose  0

rb_ary_replace  1

rb_ary_fill  -1

rb_ary_times  1

rb_ary_equal  1

rb_ary_to_s  0

rb_ary_inspect  0

rb_ary_eql  1

rb_ary_at  1

rb_ary_first  -1

rb_ary_last  -1

rb_ary_concat  1

rb_ary_push_m  -1

rb_ary_unshift  -1

rb_ary_each  0

rb_ary_join_m  -1

rb_ary_sort  0

rb_ary_sort_bang  0

rb_ary_collect  0

rb_ary_collect_bang  0

rb_ary_delete  1

rb_ary_delete_at_m  1

rb_ary_reject  0

rb_ary_reject_bang  0

rb_ary_clear  0

rb_ary_includes  1

rb_ary_compact  0

rb_ary_compact_bang  0

---

 

//Hash

rb_hash_equal  1

rb_hash_aref  1

rb_hash_aset  2

rb_hash_default  -1

rb_hash_set_default  1

rb_hash_index  1

rb_hash_indexes  -1

rb_hash_size  0

rb_hash_empty_p  0

rb_hash_each  0

rb_hash_sort  0

rb_hash_keys  0

rb_hash_values  0

rb_hash_shift  0

rb_hash_delete  1

rb_hash_select  0

rb_hash_reject  0

rb_hash_reject_bang  0

rb_hash_clear  0

rb_hash_invert  0

rb_hash_has_key  1

rb_hash_has_value  1

<!BASIC RUBY FUNC>

 

//Class Variable

rb_mod_remove_cvar 

rb_define_class_variable 

rb_cvar_defined 

mod_av_set 

rb_cvar_get 

rb_cvar_set 

rb_cv_get 

rb_cv_set 

---

 

//Constantes

rb_const_set 

rb_define_const 

rb_const_defined_at 

rb_const_defined 

rb_const_defined_from 

rb_const_defined_0 

rb_mod_remove_const 

rb_const_get_at 

rb_const_get 

rb_const_get_from 

rb_const_get_0 

rb_define_global_const 10068320

---

 

//Instance Variable

rb_ivar_get 

rb_attr_get 

rb_ivar_set 

rb_ivar_defined 

rb_obj_remove_instance_variable 

rb_iv_get 

rb_iv_set 

---

 

//Global Variable

rb_gv_set 

rb_gv_get 

rb_gvar_defined 

---

 

//Object

rb_obj_clone 

rb_obj_dup 

---

 

//Class

rb_funcall2 

rb_funcall3 

rb_define_sigleton_method 1005F1E0

rb_define_method 1005EF70

rb_define_global_function 1005F270

rb_define_module 1005E990

rb_define_class_under 

rb_define_class 1005E740

rb_define_module_under 

rb_class_new 

rb_define_class_id 

rb_class_boot 

rb_set_class_path 

rb_class_inherited 

rb_mod_included_modules 

rb_mod_include_p 

rb_mod_ancestors 

rb_singleton_class 

rb_define_private_method 1005EFA0

rb_define_module_function 

rb_define_alias 1005F2C0

rb_define_attr 

rb_scan_args 

rb_undef_method 1005EFD0

rb_include_module 1005EBC0

---

 

ruby_xmalloc 

ruby_xrealloc 

ruby_xfree 

ruby_xcalloc 

 

//ENDEF FUNCT//

 

 

 

Macros :

#define FIXNUM_P(a) a&0x00000001

#define SYMBOL_P(a) (a&0x000000FF)==0x0e

#define NIL_P(a) a==0x04

 

RGSSInitialize 

RGSSGameMain 

RGSSSetupRTP 

 

 

Classes

    kAudio ,

    kGraphics ,

    kInput ,

    kObject 102AC098,

    kModule ,

    kClass ,

    kKernel 102AC080,

    kNilClass 102AC090,

    kSymbol ,

    kTrueClass 102AC094,

    kData 102AC078,

    kFalseClass 102AC088,

    kArray 102ABFE8,

    kString ,

    kFloat ,

    kInteger ,

    kNumeric ,

    kSprite ,

    kBitmap ,

    kViewport ,

    kRect ,

    kTone ,

    kColor ,

    kFont ,

  eTypeError ,

  eArgError ,

  eIndexError ,

  eException ,

  eStandardError ,

  kHash
@Drago del Fato : Using ruby API will make your Game crash, I tried Win32API.new("socket.so","Init_Socket","","").call() looong time ago and the result was "RGSS Player a cessé de fonctionner.". But it's right : the arguments of the functions didn't change.
That address for define module didn't work for me the first time round, I'll try them all out tonight and see about writting a wrapper to easily get native classes into RGSS.
 
Where would I call the define class and define methods in the exe? Just before GameMain or after initialise3 or anywhere else? I'm getting a crash with define_class at the moment

EDIT: Got it all working now, guess it's time to write a wrapper for this stuff

When I have time I'll search for the rb_define_class_variable rb_data_object_alloc pointers

EDIT2: As an update on where I'm going with this, I'm attempting to get an OpenGL render loop on top of the game screen, I have some ideas for this and some tests have proven successful (I can insert OpenGL draw calls, albeit they flicker like crazy because it's mixed with GDI).

What I'm going to try is drawing OpenGL to a framebuffer and copying the memory to an RGSS3 picture, which can be drawn by the game when it wants, I need some help with accessing the picture class though, so if anyone wants to help me here then please do
 
Xilef":37hcdkg5 said:
Where would I call the define class and define methods in the exe? Just before GameMain or after initialise3 or anywhere else? I'm getting a crash with define_class at the moment

EDIT: Got it all working now, guess it's time to write a wrapper for this stuff

When I have time I'll search for the rb_define_class_variable rb_data_object_alloc pointers

EDIT2: As an update on where I'm going with this, I'm attempting to get an OpenGL render loop on top of the game screen, I have some ideas for this and some tests have proven successful (I can insert OpenGL draw calls, albeit they flicker like crazy because it's mixed with GDI).

What I'm going to try is drawing OpenGL to a framebuffer and copying the memory to an RGSS3 picture, which can be drawn by the game when it wants, I need some help with accessing the picture class though, so if anyone wants to help me here then please do

The picture class, or the bitmap class? If it's the bitmap class, there are some copies of a .dll source in my post history that take the address for a bitmap that Ruby provides, and loads them into moddable memory.
 
Glitchfinder":2h06o4qh said:
The picture class, or the bitmap class? If it's the bitmap class, there are some copies of a .dll source in my post history that take the address for a bitmap that Ruby provides, and loads them into moddable memory.
I don't see an exposed bitmap class for RGSS3, I was going to go and mess about with the picture class until I find a handle to something vaguely bitmap-esque.

Anything that gives access to a raw image that can be displayed within a standard RGSS3 game is what I'm looking for

Is Sprite_Picture useful at all for this?
 
Xilef":1uok0hc2 said:
Glitchfinder":1uok0hc2 said:
The picture class, or the bitmap class? If it's the bitmap class, there are some copies of a .dll source in my post history that take the address for a bitmap that Ruby provides, and loads them into moddable memory.
I don't see an exposed bitmap class for RGSS3, I was going to go and mess about with the picture class until I find a handle to something vaguely bitmap-esque.

Anything that gives access to a raw image that can be displayed within a standard RGSS3 game is what I'm looking for

Is Sprite_Picture useful at all for this?

I got the data via having a Bitmap instance in RGSS, and passing it to the dll via bitmapInstance.__ID__, I think. It's been a while since I've done it, so I'm not sure what the specific call was. You can find one of the posts with a .dll source here, if you want to take a look. And, I just checked to be sure. RGSS, RGSS2, and RGSS3 all use the Bitmap class, as stated.
 
Okay thanks, I found the source so I'm all set, cheers.

EDIT: The .__id__ left shift thing doesn't seem to work (At least with RGSS301), so I'm scratching my head at this point

Perhaps there is a different calling convention between Win32API and an internal call
 
You can send a bitmap to a C function or create the bitmap in the function before returning it ^^'
C:
<div class="c" id="{CB}" style="font-family: monospace;"><ol>VALUE Graphics_snap_to_bitmap(VALUE self)

{

    VALUE args[<span style="color: #cc66cc;">2]={GWidth,GHeight};

    VALUE obitmap=rb_class_new_instance(<span style="color: #cc66cc;">2,args,RGSSConst(kBitmap));

//Some stuff -._-.

    memcpy(RBITMAP(obitmap)->bm->bminfo->lastRow,lpbitmap,dwBmpSize);

//Some cleaning stuff -._-.

    <span style="color: #b1b100;">return obitmap;

}
 
Don't do it with its ID :b
C:
<div class="c" id="{CB}" style="font-family: monospace;"><ol><span style="color: #993333;">struct RGSSBMINFO{

    DWORD unk1;

    DWORD unk2;

    BITMAPINFOHEADER *infoheader;

    LPBYTE firstRow; //RGBQUAD *firstRow;

    LPBYTE lastRow;

};

 

<span style="color: #993333;">struct BITMAPSTRUCT {

    DWORD unk1;

    DWORD unk2;

    RGSSBMINFO *bminfo;

};

 

<span style="color: #993333;">struct RGSSBITMAP {

    <span style="color: #993333;">struct RBasic basic;

    <span style="color: #993333;">void (*dmark)(<span style="color: #993333;">void*);

    <span style="color: #993333;">void (*dfree)(<span style="color: #993333;">void*);

    BITMAPSTRUCT *bm;

};

<span style="color: #339933;">#define RBITMAP(obj)   (R_CAST(RGSSBITMAP)(obj))

 

VALUE Function_that_receive_a_bitmap(VALUE self,VALUE object)

{

  rb_check_type(object,T_DATA); //Checking if it's a DATA object. (Bitmap Are Data Object)

  <span style="color: #993333;">struct RGSSBITMAP* bitmap=RBITMAP(object); //Not sure for "RGSSBITMAP*"

  <span style="color: #b1b100;">if(bitmap->basic.<span style="color: #202020;">klass != RGSSConst(kBitmap)) //RGSSConst(kbitmap) is the bitmap class, you should define it somewhere.

  {

    rb_raise(RGSSConst(eArgError),"Argument is not a Bitmap.");

    <span style="color: #b1b100;">return <span style="color: #cc66cc;">0;

  }

  //Do your stuff here

 

  <span style="color: #b1b100;">return <span style="color: #cc66cc;">2;//true

}
Bitmaps should probably have a different structure in RGSS2, checks it by reading the memory of a Bitmap object ^^'
 
You can also use Ruby macro Data_Get_Struct for getting DATA from Ruby objects (copied from ruby.h from include folder in source code of ruby interpreter):

Code:
 

struct RBasic {

    VALUE flags;

    const VALUE klass;

}

 

struct RData {

    struct RBasic basic;

    void (*dmark)(void*);

    void (*dfree)(void*);

    void *data;

};

 

#define R_CAST(st)   (struct st*)

#define RDATA(obj)   (R_CAST(RData)(obj))

#define DATA_PTR(dta) (RDATA(dta)->data)

#define Check_Type(v,t) rb_check_type((VALUE)(v),(t))

 

#define Data_Get_Struct(obj,type,sval)

    Check_Type((obj), T_DATA); \

    (sval) = (type*)DATA_PTR(obj);\

} while (0)

 

Basically getting the data from ruby variables would amount up to:
Code:
 

structure_type *destination_var;

Data_Get_Struct(ruby_variable, structure_type, destination_var);

 

// Use destination_var for what you need. If there is no DATA inside ruby variable, ruby error will be raised.

 

Data types are basically memory pointers to C structures (or C++ objects) stored inside Ruby variable, this way you can make Ruby class wrappers of C structures and not worry about where they are referenced. This one is really vaguely explained inside ruby documentation (especially stuff when making your own Native API Ruby classes. I had to find a lot about it by hand).
 
Nuri Yuri":3b09z6m6 said:
Don't do it with its ID :b
C:
<div class="c" id="{CB}" style="font-family: monospace;"><ol><span style="color: #993333;">struct RGSSBMINFO{

    DWORD unk1;

    DWORD unk2;

    BITMAPINFOHEADER *infoheader;

    LPBYTE firstRow; //RGBQUAD *firstRow;

    LPBYTE lastRow;

};

 

<span style="color: #993333;">struct BITMAPSTRUCT {

    DWORD unk1;

    DWORD unk2;

    RGSSBMINFO *bminfo;

};

 

<span style="color: #993333;">struct RGSSBITMAP {

    <span style="color: #993333;">struct RBasic basic;

    <span style="color: #993333;">void (*dmark)(<span style="color: #993333;">void*);

    <span style="color: #993333;">void (*dfree)(<span style="color: #993333;">void*);

    BITMAPSTRUCT *bm;

};

<span style="color: #339933;">#define RBITMAP(obj)   (R_CAST(RGSSBITMAP)(obj))

 

VALUE Function_that_receive_a_bitmap(VALUE self,VALUE object)

{

  rb_check_type(object,T_DATA); //Checking if it's a DATA object. (Bitmap Are Data Object)

  <span style="color: #993333;">struct RGSSBITMAP* bitmap=RBITMAP(object); //Not sure for "RGSSBITMAP*"

  <span style="color: #b1b100;">if(bitmap->basic.<span style="color: #202020;">klass != RGSSConst(kBitmap)) //RGSSConst(kbitmap) is the bitmap class, you should define it somewhere.

  {

    rb_raise(RGSSConst(eArgError),"Argument is not a Bitmap.");

    <span style="color: #b1b100;">return <span style="color: #cc66cc;">0;

  }

  //Do your stuff here

 

  <span style="color: #b1b100;">return <span style="color: #cc66cc;">2;//true

}
Bitmaps should probably have a different structure in RGSS2, checks it by reading the memory of a Bitmap object ^^'

I tried without ID, which nearly works, but the struct looks totally misaligned so I suppose that the struct format has changed between versions
 
I'm bumping this with some news.

In a continuation with my bitmap experiments in this exe, I made a union to look through the bitmap class to try and find something related to my input bitmap.

I gave the function the title screen background bitmap (544 x 416 in resolution) and made a union that had 16 32bit integers against 16 pointers to the same union type, I search around a bit for the resolution of the image and found this:
r0Fy3LD.png


So I'm going to write an RGSS3 bitmap struct mapping now

EDIT: Looks like this isn't a consistent value, changes every now and then to large numbers, so it must be pointing to some other memory location, oh well.
 
I believe it's a pointer to something else as it changes to weird values every other launch of the game, so it could be anything unfortunately.
 
RGSS3 bitmaps are the same as RGSS1 bitmaps :
143-43451c0.png

I did :
Code:
@a=Bitmap.new(8,8)

@a.set_pixel(1,1,Color.new(255,0,255,128))

raise "#{(@a.object_id*2).to_s(16)}"
 
The RGSS1 bitmap functions really don't work for me, the bitmap header is always an invalid pointer and the adjacent pointers don't match as the header either
 
Aha I got it working, I didn't realise that the first argument for Global functions is the calling module, what I was doing was shifting around the pointers to find the bitmap, I added param 1 to the function and now it all works.

Guess that teaches me to learn Ruby before trying to dick around with it, sorry for being sucky, I'll package up and release what I've done.
 
Status
Not open for further replies.

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