Game Maker Community YoYo Games

Welcome Guest ( Log In | Register )

> 

This forum provides a place to post your Dlls, Scripts, Libraries and Extensions for GM. Be sure to read these rules prior to posting. The guidelines for each sub-forum are pinned at the top of that forum.

3 Pages V   1 2 3 >  
Reply to this topicStart new topic
Gmapi, Library for VC++ that is helpful in writing DLLs for GM
Snake_PL
post Apr 22 2009, 02:25 PM
Post #1


GMC Member
Group Icon

Group: GMC Member
Posts: 22
Joined: 2-December 07
From: Poland
Member No.: 94338



Last update: 17 may 2009
Current version: 0.4

About...

GMAPI is a library for Visual C++ that is helpful in writing DLLs for Game Maker 6.1 and 7.0. What it can do ? Features:
  • Call GML functions directly from Your DLL
  • Direct access to game resources via GM's structures (actually, those are classes in runner) located in memory and with GMAPI interfaces, including:
    • Pointers to sprites' and backgrounds' bitmaps
    • Pointers to sound files loaded to memory by the runner
    • Resource properties & data (e.g. sprite's height, bounding box, script's code etc...)
    • Direct3D interfaces such as: IDirect3D8, IDirect3DDevice8, IDirect3DTexture8 (textures of sprites, backgrounds & surfaces loaded in vram) [GM uses Direct3D 8]
    • GM local/global variables & arrays
    • Instance's builtin variables (x, y, direction etc.)
In the current version You can access sprites, backgrounds, surfaces, sounds, scripts and other data (such as pointers to D3D interfaces, window handles, pointers to GML functions, GM version...). Soon I'll try to give You possibility to access other runner's data as well... I'm also thinking about adding new features like adding a sprite to game from bitmap loaded in memory. Well, You can give suggestions what could be added to the library (BTW. something important/useful related to DirectX will be welcomed - I don't know much about that library ;p). Unfortunatelly, because of lack of time i didn't wrote a documentation... there are only some examples & comments in a header file... here i'll explain most important things.
Library is released on LGPL license, so everyone can take a look at the source and check out how it is made, or modify... tongue.gif
When project will be in more advanced stage (and there will be time for this ofc) i'll make the library compatible with MinGW compiler ;o

Using the library

Installation
All You have to do is extract the archive to chosen directory and specify the paths to "include" & "lib" directories in IDE. Run Visual C++, select from "Tools" menu "Options..." item, next go to "Projects and Solutions" >> "VC++ Directories" node, now select "Include files" from the "Show directories for" combobox and add the path to "include" directory from GMAPI, then select "Library files" from the combobox and add the path to "lib" directory. Done.
Initialization
Before you'll begin to work with the library You must include gmapi.h header to one of the source files in Your project. If You don't have DirectX SDK installed define GMAPI_NO_D3D before including gmapi.h (D3D interfaces will be defined as void), thus this will look like:
CODE
#define GMAPI_NO_D3D
#include <gmapi.h>
Now You must add to the library dependencies proper static library - all depends on which runtime library You choose in Your project:
gmapi-mt.lib - Multithreaded
gmapi-mt-dll.lib - Multithreaded DLL
gmapi-mt-d.lib - Multithreaded debug
gmapi-mt-d-dll.lib - Multithreaded debug DLL

Next, You must create main library object, that is CGMAPI class. That class is a singleton, so only one instance can be created at runtime in Your library. To create an instance of this class use CGMAPI::Create static method, which takes as parameter a pointer to "unsigned long" variable type - it'll be used to return the result of initialization (possible values are: GMAPI_INITIALIZATION_SUCCESS - if initialization succeeded; GMAPI_INITIALIZATION_FAILED - when initialization fails; GMAPI_ALREADY_INITIALIZED - when an instance of CGMAPI class already exists). The method returns pointer to newly created class object, which You should store in a variable. I recommend to do this in DLL's entrypoint, that is DllMain function, for example:
CODE
gm::CGMAPI* gmapi;

BOOL WINAPI DllMain( HINSTANCE aModuleHandle, int aReason, int aReserved ) {
  switch ( aReason ) {
    case DLL_PROCESS_ATTACH: {
      // Initialization
      unsigned long result = 0;
      gmapi = gm::CGMAPI::Create( &result );

      // Check the result
      if ( result != gm::GMAPI_INITIALIZATION_SUCCESS ) {
        MessageBox( 0, "Unable to initialize GMAPI.", 0, MB_SYSTEMMODAL | MB_ICONERROR );
        return FALSE;
      }

      break;
    }

    case DLL_PROCESS_DETACH:
      // Release from memory & deinitialize GMAPI
      gmapi->Destroy();
      break;
  }

  return TRUE;
}

CGMAPI::Destroy() method frees the class instance from memory. BTW, all classes, functions, constants etc. in GMAPI are declared in "gm" namespace. You should not call any GML functions immediatelly after initialization - GMAPI hooks external_call function in runner in order to retrieve pointer to current instance (that is, from which the function is called) which is needed to call all GM functions properly in DLL. So, it is necessary to return to GM after initialization. When class object has been created without any problems You can call the GML functions from within Your DLL and, of course, You can use CGMAPI class components.
Calling GM functions
When GMAPI is initialized You can now call GM functions from the DLL. All functions are nicely wrapped in the library so You can call them in a simple way, take a look:
CODE
int list;
gm::CGMVariable value;

list = gm::ds_list_create();

gm::ds_list_add( list, "test" );
gm::ds_list_add( list, 12345.12345 );

value = gm::ds_list_find_value( list, 0 ); // store "test" in the variable
value = gm::ds_list_find_value( list, 1 ); // return 12345.12345 to the variable

gm::ds_list_destroy( list );

CGMVariable class object that is defined in this code snippet mimics the GM variable, so it can be set to either string or real value. It must be used to store return values from functions that can return values that type is not known (e.g. ds_list_find_value can return either string or real). Also, You must pass it in parameters in some GM functions for the same reason... besides, that class emulates string type from Delphi - it deals with string allocation, "conversion" from char*, deallocation etc... using runner - char* is not fully compatible with Delphi string ("length" variable, reference counter for the garbage collector) so i had to do something ^^ Oh, one more thing... You should always return the result of GM function that can return string to the CMGVariable class object - it'll take care of deallocation.
All GM functions are available in GMAPI, excluding math functions and those that are operating on strings (and functions such as is_real or is_string). In addition, class has some constructors overloaded and it can be instatiated implicitly by passing a value in parameters that type is a reference to a CGMVariable class (e.g. ds_list_add takes CGMVariable reference type in second parameter, in above code snippet there will be created an temporary instance of class by passing "char*" or "double" to the function). There are also some operator overloading implemented, like "++", "-=" or casting to double/char*, plus "<<" overload for std::ostream biggrin.gif
Accessing game resources
You can access them by a three ways: with GM functions of course (least efficent, less possibilities), by GM's structures that I've analyzed in runner and with "accessing classes" defined in GMAPI. Using structures is most efficent and equally unsafe, I'll explain how to use them in a documentation that I'll write later. Meanwhile, You can use the classes I mentioned - they're safer and easier to use than using the GM's structures. Why I called them "accessing" (wtf) ? Well, they're operating entirely on runner's memory, what is also reason why using them is somewhat entangled. In CGMAPI class there are some objects of these classes defined: Sprites (ISprites class), Backgrounds (IBackgrounds), Sounds (ISounds), Surfaces (ISurfaces) and Scripts (IScripts). All of these classes shares some methods that can retrieve various data that is relevant to respective GM resource type (for example, GetID() returns an ID of specified resource by given name of this type, GetCount() returns number of resources of this type) and all of them have an array operator ("[]") overloaded that returns reference type to next "accessing classes" - these classes gives You access to resource with ID specified in brackets. Damn, hard to explain... so, for example:
CODE
gm::CGMAPI* gmapi;
(...)
// Let's say that we've added an animated sprite named spr_anim
// to the game, now we want to get width of the sprite
int sprAnim, spriteWidth;

// First, we must get the ID
sprAnim = gmapi->Sprites.GetID( "spr_anim" );

// Now we will get the width
spriteWidth = gmapi->Sprites[sprAnim].GetWidth();

// What if our sprite has not been found because we didn't added it
// to the game ? An exception with EGMAPISpriteNotExists class object will be thrown
// (exception class), we will catch it with "try - catch" of course
try {
  spriteWidth = gmapi->Sprites[sprAnim].GetWidth();
}
catch ( gm::EGMAPISpriteNotExist& exc ) {
  exc.ShowError(); // Show message with information about error
}

// Operator [] in ISprites class returns ISprite reference type - that class is
// the only one of these "higher level" that have defined object of next such
// class - ISpriteSubimages (Subimages object), which gives You access to specified
// sprite subimage. Hm, let's say we want to store all of the texture ID (a'la
// sprite_get_texture from GM) in a vector array:
std::vector<int> textures;

for ( int i = 0; i < gmapi->Sprites[sprAnim].Subimages.GetCount(); i++ )
  textures.push_back( gmapi->Sprites[sprAnim].Subimages[i].GetTextureID() );

Well, that's all about accessing game resources.
Notes:
As I mentioned before, I'll write a documentation later. Meanwhile, You have to rely on IntelliSense, comments in GmapiInternal.h header file and on 3 crappy examples I wrote ;p In GMAPI there are also constants from GM. Of course please report all bugs You've found - project is still in testing stage.
Download:

GMAPI v0.4 + src:
http://gmclan.org/up541_4_GMAPIv0_4_src.html

GMAPI v0.4 - MinGW version (thanks to 39ster):
http://host-a.net/39ster/GMAPIv04src.rar
You may need to link GMAPICore\GMAPICore.lib along with libGMApiRelease.a library to successfully compile your DLL.

GMAPI v0.3 + src:
http://gmclan.org/up541_4_GMAPIv0_3_src.html

GMAPI v0.2 + src:
http://gmclan.org/up541_4_GMAPIv0_2_src.html

GMAPI v0.1 + src:
http://gmclan.org/up541_4_GMAPIv0_1_src.html

Examples:

My BBCode engine ( http://forum.gmclan.org/index.php?showtopic=15031 ) rewritten to C++:
src: http://gmclan.org/up541_4_BBCodeEngineSrc.html
demo: http://gmclan.org/up541_4_BBCodeEngineDemo.html

Bitmap viewer:
src: http://gmclan.org/up541_4_BitmapViewerSrc.html
demo: http://gmclan.org/up541_4_BitmapViewerDemo.html

Direct3D interfaces test (hardcoding crap biggrin.gif):
src: http://gmclan.org/up541_4_D3DexampleSrc.html
demo: http://gmclan.org/up541_4_D3DexampleDemo.html

Example of accessing GM variables:
src: http://gmclan.org/up541_4_GmapiVariablesSrc.html
demo: http://gmclan.org/up541_4_GmapiVariablesDemo.html


DLLs that uses GMAPI:
Advanced console by TheMagicNumber
gmLua by Kofel


This post has been edited by Snake_PL: Sep 6 2009, 10:39 PM
Go to the top of the page
 
+Quote Post
gnysek
post Apr 22 2009, 02:47 PM
Post #2


GMC Member
Group Icon

Group: GMC Member
Posts: 45
Joined: 16-June 04
From: GdaƄsk, Poland
Member No.: 10578



Thanks dude, it's awesome!
Go to the top of the page
 
+Quote Post
paul23
post Apr 22 2009, 03:17 PM
Post #3


GMC Member
Group Icon

Group: GMC Member
Posts: 1697
Joined: 1-March 05
From: Here in holland
Member No.: 23016



Well as I said in pm, maybe inverse the usage of d3d8.h: it's nowadays difficult to get the directx8 develop thing, (you can't get from MSDN anymore) - so you'll always have to add this line:
CODE
#define GMAPI_NO_D3D


maybe make it so that d3d8.h is ONLY used if something is defined....
Go to the top of the page
 
+Quote Post
Snake_PL
post Apr 22 2009, 03:25 PM
Post #4


GMC Member
Group Icon

Group: GMC Member
Posts: 22
Joined: 2-December 07
From: Poland
Member No.: 94338



Ok, I'll correct that in next version.
Go to the top of the page
 
+Quote Post
ditdingiscool
post Apr 25 2009, 08:36 AM
Post #5


GMC Member
Group Icon

Group: GMC Member
Posts: 337
Joined: 6-October 07
Member No.: 90046



hi there, i'm kindoff new to c/c++ so i neaad some help setting this up, especialy what do i have to do EXACTLY when you say this:
QUOTE
Now You must add to the library dependencies proper static library - all depends on which runtime library You choose in Your project:
gmapi-mt.lib - Multithreaded
gmapi-mt-dll.lib - Multithreaded DLL
gmapi-mt-d.lib - Multithreaded debug
gmapi-mt-d-dll.lib - Multithreaded debug DLL

(using dev c++)

thanks already tongue.gif
Go to the top of the page
 
+Quote Post
Tuntis
post Apr 25 2009, 10:47 AM
Post #6


I am stupid
Group Icon

Group: GMC Member
Posts: 2115
Joined: 27-October 03
From: Finland
Member No.: 707



QUOTE (ditdingiscool @ Apr 25 2009, 11:36 AM) *
(using dev c++)

read
Go to the top of the page
 
+Quote Post
ditdingiscool
post Apr 25 2009, 01:31 PM
Post #7


GMC Member
Group Icon

Group: GMC Member
Posts: 337
Joined: 6-October 07
Member No.: 90046



QUOTE (Tuntis @ Apr 25 2009, 12:47 PM) *
QUOTE (ditdingiscool @ Apr 25 2009, 11:36 AM) *
(using dev c++)

read

that page doesn't give any real argument, it only has one weak argument "it's outdated", but so is windows xp and that sucks less than vista, but ok, whatever, downloading code::blocks

EDIT:ok, that really solved nothing,
QUOTE
Process terminated with status 1 (0 minutes, 4 seconds)
50 errors, 22 warnings



This post has been edited by ditdingiscool: Apr 25 2009, 01:45 PM
Go to the top of the page
 
+Quote Post
freaked
post Apr 25 2009, 01:54 PM
Post #8


freak up!
Group Icon

Group: GMC Member
Posts: 898
Joined: 7-April 07
From: India
Member No.: 75612



Post some of those 50 errors.
Most probably they'll be linker related errors.
Also,(AFAIK) you'll have to convert those .lib files to .a archives for GCC's linker to use.
Use a tool in your bin folder called REIMP to do this.

Also Snake_PL, what do you use to hook d3d functions ?

This post has been edited by freaked: Apr 25 2009, 01:56 PM
Go to the top of the page
 
+Quote Post
Tuntis
post Apr 25 2009, 01:58 PM
Post #9


I am stupid
Group Icon

Group: GMC Member
Posts: 2115
Joined: 27-October 03
From: Finland
Member No.: 707



QUOTE (ditdingiscool @ Apr 25 2009, 04:31 PM) *
it only has one weak argument "it's outdated", but so is windows xp and that sucks less than vista, but ok, whatever, downloading code::blocks

...Except that XP is not outdated because MS still provides support for it.
Go to the top of the page
 
+Quote Post
TheMagicNumber
post Apr 25 2009, 03:11 PM
Post #10


GMC Member
Group Icon

Group: GMC Member
Posts: 3746
Joined: 9-December 07
Member No.: 94888



If nobody is working on it, can you work on a Code::Blocks version? (Tuntis, if you ever tell me to use VC++, I despise Microsoft products)

By the way, Windows XP was unsupported for a while, but they extended the support, probably because many people downgraded from Windows Vista.
Go to the top of the page
 
+Quote Post
Tuntis
post Apr 25 2009, 04:33 PM
Post #11


I am stupid
Group Icon

Group: GMC Member
Posts: 2115
Joined: 27-October 03
From: Finland
Member No.: 707



QUOTE (GMREC1111 @ Apr 25 2009, 06:11 PM) *
(Tuntis, if you ever tell me to use VC++, I despise Microsoft products)

Well, if you intend on using this thing right now, I can tell you that VC++ Express will be the quickest and most pain-free solution...
Go to the top of the page
 
+Quote Post
GearGOD
post Apr 25 2009, 04:57 PM
Post #12


Deus Verus
Group Icon

Group: GMC Member
Posts: 1827
Joined: 18-December 04
From: Land of Twilight
Member No.: 18164



QUOTE
Tuntis, if you ever tell me to use VC++, I despise Microsoft products

You're not using a dev tool because you despise that company that its affiliated with? Even though its arguably the best one around and free? You're so awesome.
Go to the top of the page
 
+Quote Post
ditdingiscool
post Apr 26 2009, 07:25 AM
Post #13


GMC Member
Group Icon

Group: GMC Member
Posts: 337
Joined: 6-October 07
Member No.: 90046



QUOTE (GearGOD @ Apr 25 2009, 06:57 PM) *
QUOTE
Tuntis, if you ever tell me to use VC++, I despise Microsoft products

You're not using a dev tool because you despise that company that its affiliated with? Even though its arguably the best one around and free? You're so awesome.

i'm also not a big fan off vc++, and not only because it's from micro$oft, it has 'adobe reader syndrome'(load a document, have lunch, wait another 10 minutes for it to load), and it isn't able to create empty projects on my pc...

ONTOPIC:
CODE
||=== vonoroi, default ===|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|32|warning: `GMDeallocateString' initialized and declared `extern'|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|32|error: variable or field `GMDeallocateString' declared void|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|32|error: `gm::core::GMDeallocateString' declared as an `inline' variable|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|32|warning: `__stdcall__' attribute only applies to function types|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|32|error: `__in' was not declared in this scope|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|33|warning: `GMDeallocateResult' initialized and declared `extern'|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|33|error: variable or field `GMDeallocateResult' declared void|
C:\Documents and Settings\lieuwe\Bureaublad\bende\GMAPI\dll_vonoroi\GmapiCore.h|33|error: `gm::core::GMDeallocateResult' declared as an `inline' variable|
<snip>
||More errors follow but not being shown.|
||Edit the max errors limit in compiler options...|
||=== Build finished: 50 errors, 22 warnings ===|
Go to the top of the page
 
+Quote Post
X-tra Fear
post Apr 26 2009, 09:11 AM
Post #14


Behemoth Creator
Group Icon

Group: GMC Member
Posts: 439
Joined: 11-October 06
From: Kingsport, Tennessee
Member No.: 61283



Honestly, I think you should have made this compatible with the GCC compiler also.

QUOTE
You're not using a dev tool because you despise that company that its affiliated with? Even though its arguably the best one around and free? You're so awesome.


Errr, he's not trying to be awesome, he has just been mis-guided about Microsoft products.

A lot of them are actually pretty good, and VC++ is one of them.
Honestly, if you were to ever download a Microsoft product, I reccomend you try that one.

Download Visual C++ Express

You could have at least been helpful GearGod. :/

EDIT: Honestly, I think GMREC uses linux anyway, and I have no clue why he is really worrying about Game Maker in the first place... I don't think WINE can even run it.

This post has been edited by X-tra Fear: Apr 26 2009, 09:16 AM
Go to the top of the page
 
+Quote Post
Tuntis
post Apr 26 2009, 10:27 AM
Post #15


I am stupid
Group Icon

Group: GMC Member
Posts: 2115
Joined: 27-October 03
From: Finland
Member No.: 707



QUOTE
Errr, he's not trying to be awesome

Oh trust me, this guy refuses to use pretty much any Microsoft technology because it's a "giant fag company". Funny how he still uses Windows...
Go to the top of the page
 
+Quote Post
X-tra Fear
post Apr 26 2009, 11:18 AM
Post #16


Behemoth Creator
Group Icon

Group: GMC Member
Posts: 439
Joined: 11-October 06
From: Kingsport, Tennessee
Member No.: 61283



QUOTE (Tuntis @ Apr 26 2009, 10:27 AM) *
QUOTE
Errr, he's not trying to be awesome

Oh trust me, this guy refuses to use pretty much any Microsoft technology because it's a "giant fag company". Funny how he still uses Windows...


Ohhhh, I don't really know him all that well... lol.
Go to the top of the page
 
+Quote Post
freaked
post Apr 26 2009, 12:00 PM
Post #17


freak up!
Group Icon

Group: GMC Member
Posts: 898
Joined: 7-April 07
From: India
Member No.: 75612



Lol. GMREC and me even had PM discussion involving C::B's greatness and MSVC's suckiness.
Go to the top of the page
 
+Quote Post
TheMagicNumber
post Apr 26 2009, 02:00 PM
Post #18


GMC Member
Group Icon

Group: GMC Member
Posts: 3746
Joined: 9-December 07
Member No.: 94888



QUOTE (Tuntis @ Apr 26 2009, 06:27 AM) *
Funny how he still uses Windows...

Rarely.

And I did want a GCC version.
Go to the top of the page
 
+Quote Post
icuurd12b42
post Apr 26 2009, 11:58 PM
Post #19


GMC Member
Group Icon

Group: GMC Member
Posts: 7682
Joined: 26-October 06
Member No.: 62394



What is weird is your DLLMain, which is proper to use in that manner but... I found out a while back in my dlls that this is never called for dll's used by GM (7)
Go to the top of the page
 
+Quote Post
paul23
post Apr 27 2009, 10:34 PM
Post #20


GMC Member
Group Icon

Group: GMC Member
Posts: 1697
Joined: 1-March 05
From: Here in holland
Member No.: 23016



QUOTE (icuurd12b42 @ Apr 27 2009, 01:58 AM) *
What is weird is your DLLMain, which is proper to use in that manner but... I found out a while back in my dlls that this is never called for dll's used by GM (7)

? - Uhm well I found out that they are actually called, DLL_PROCESS_ATTACH, when you 'initialize' your first function.. And DLL_PROCESS_DETTACH when you unload the dll. (Also using GM 7)
Go to the top of the page
 
+Quote Post

3 Pages V   1 2 3 >
Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 



RSS Lo-Fi Version Time is now: 20th November 2009 - 10:31 PM