Legacy GM get_function_address('function_name')

Discussion in 'Advanced Programming Discussion' started by Samuel Venable, Feb 14, 2018.

  1. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    Edit: Anyone else want this feature? YoYo responded to my ticket saying they would consider it in a future release if enough people on the GMC wanted it! :D (Original topic contents below, but the discussion has changed to requesting this function).

    Anyone know what this function from GM 8.1 does? I'm not really clear on this. Not very well documented.
    That quote was taken from the bottom of this webpage: http://gamemaker.info/en/manual/414_00_dlls

    It sounds like something that could be really really useful for extension writers if YoYo brought the function back in GameMaker Studio. I have a couple guesses as to what it does, but it's still a little confusing to me...

    Is it basically a way to call a function from a string?

    I tried this in 8.1 but nothing happened, (it returns -1):
    Code:
    get_function_address('show_message("poop")')
    So I tried getting the return value with this, (using just 'show_message'):
    Code:
    get_string("",string(get_function_address('show_message')));
    And it outputted in the textbox this:
    Code:
    6567176
    So that's the address, I guess... Not sure what I do with it?

    Thanks!
    Samuel
     
    Last edited: Feb 18, 2018
    MaddeMichael and Dogarooski like this.
  2. Tthecreator

    Tthecreator Your Creator!

    Joined:
    Jun 20, 2016
    Posts:
    740
    In the first example I guess you were looking for the stack frame of the function being called in the ''.
    Yea it doesn't quite work that way.
    Well when you load a game, every instruction needed is put into ram, including every game maker function.
    So it gives you that address, which is a very general address and doesn't change depending on how much or how you run the function.

    In cpp you could probably do something like

    void (*foo)(int);
    foo = &theAdressAsGivenByGM

    //now just call it:
    foo(3);

    You might also need to do some weird double to address conversion schemes.

    I hope that clarifies things. This would indeed be useful in gamemaker but I'm not sure whether the yoyo guys will actually take the time implementing this. I'd still love to see it though.
     
    Samuel Venable likes this.
  3. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    Ah, I gotcha. That makes sense. I'll play around with the casting if the example you gave as a base doesn't work. It would be super cool if they at least made it work on Windows, if nothing else, since that's what legacy GM ran on. (I don't know if GM4Mac had this function, probably not...)

    Thank you! :D

    (I think I'll make a helpdesk ticket requesting this feature).

    Edit:

    Ticket submitted.
     
    Last edited: Feb 15, 2018
    Lonewolff likes this.
  4. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    Anyone else want this feature? YoYo responded to my ticket saying they would consider it in a future release if enough people on the GMC wanted it! :D
     
  5. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    4,316
    I would love to see this feature or a comparable equivalent. Imagine what would happen if we allow extensions direct access to:
    • Data structures: Extensions would then be able to take full data structure models as input and directly process them.
    • File functions: Extensions would then be able to get at files within the sandbox, which on some exports are virtual (e.g. Android, HTML5).
    • Buffers: Wouldn't be useful in native, but could still useful in HTML5 where pointers don't exist.
    • Surfaces: Computationally heavy graphics code can be delegated to native code without forcing the output to come out on top of everything else within GM.
    These are just the more obvious ones I could think of at the moment. Experienced extension developers may already be able to access these via a side channel, but a formally documented mechanism would be best for forward compatibility.

    GM7 and GM8 had a vibrant extension dev community following the publication of GMAPI. When 8.1 broke it with the new C++ runner, it completely died down. This history lesson alone is enough rationale to bring back similar functionality and also review the extensibility of GMS 2 as a whole.

    This isn't the first time I've asked for this. And if YoYo doesn't act, probably also not the last.
     
    00.Archer and Samuel Venable like this.
  6. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    I agree with your entire post. however I feel pretty certain the C++ runner wasn't introduced until GM:Studio 1.x came along, shortly after the discontinuing of GM:HTML5. I think something else in 8.1 must've broke the GMAPI. Though I could remember wrong.
     
  7. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,351
    IIRC GMAPI relied on having hardcoded offsets to some functions and internal structures so the effort of updating it whenever a GM update came out was substantial and the author had given up when GM8.1 started to get subsequent updates.

    function_get_address is an interesting thing to consider, although also oddish.
    Desktop platforms still have function addresses, though you'd have to match call convention and expected data (which prompts for more functions like getting pointers to instances).
    Android requires you to dance around JNI because you can't do anything with a C++ function address in Java.
    HTML5 would need to have a 1500 item lookup map (for function name -> function reference) inserted if the function is used.
    Things that result in VM state transition (like script_execute or event_perform) would likely require changes to VM (as you'd be interrupting it amid a DLL call to do something else entirely).
     
    Samuel Venable likes this.
  8. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,360
    Oh such functionality would be incredible!
    GML could finally be used a scripting frontend for all kinds of DLLs!
    What would be nifty is access to the renderer from DLL's too, without having GML in the middle, and without all the context manipulating bs. Just calling functions like draw_sprite from the DLL would be incredible! (GM would essentially become a C++ engine xD)
     
    Samuel Venable likes this.
  9. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    The more people who comment in this topic and/or communicate to YoYo they want this feature, one way or another, the better. Allow me to tag some people for more input on the matter.

    @Ghost in the IDE @Nocturne @zbox if anyone is aware of any other major extension writers who would potentially like this idea, please tag them! YoYo is watching this topic for Pete's sake!! :D
     
    Lonewolff likes this.
  10. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    Sounds awesome to me. :)
     
    Samuel Venable likes this.
  11. zbox

    zbox Member GMC Elder

    Joined:
    Jun 21, 2016
    Posts:
    788
    Definitely interested in this. Concerned at some of YA's points about practicality though
     
    Samuel Venable likes this.
  12. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    @zbox Well, they did say if enough people wanted it they would consider, so it must be do-able enough that they would at least be willing. But yeah, it doesn't sound like it would be very easy to implement on non-desktop platforms.
     
    zbox likes this.
  13. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,360
    Well, having support for desktop alone is good enough for me ^^
     
    Samuel Venable likes this.
  14. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
  15. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    OK this is not going to happen in the immediate future because of upcoming roadmap changes for method variables.... but the good news is that method variables are coming which could simplify what you are looking to do...

    I will consider the implications of this change for extensions, but I think what you are actually asking for is the ability to call a GML function from an extension... now this has lots of issues (mainly to do with context of the call...) but within limits it is possible to do, within a constructed context...

    This has similar issues with the Java JNI and you can read countless articles on how horrible that can get... I don't want to paint ourselves into a corner here...

    Russell
     
    Samuel Venable and zbox like this.
  16. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,360
    ooooh, is that already in the works?

    At the very least, it would be nice to call "pure" functions.

    As an extra feature, Exposing the renderer to extensions would be very nice too :)
     
  17. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,351
    You can use window_device to get a DirectX/OpenGL/... pointer to the rendering device and do what you please with it, though it is a little more DIY than calling draw_sprite directly from a DLL.
     
  18. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,360
    yeah, I know you can do that, but then why am i using GM?
    I would love to have access to GM's rendering engine, without having to deal with GML's shortcomings sometimes.
    It really is a shame to have such a great engine, with a language like GML to interface with it.
     
  19. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    We have no plans to expose the internal rendering functions for extensions, we have talked about it internally but we do not have the resources to do this at this time

    Russell
     
  20. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    This could be used in my Microsoft Script Control extension to make a fully functional GML interpreter, with strict syntax checking. (an error will close the game if the strict syntax is incorrect or if there is a missing semicolon, etc.) Since JScript and GML have nearly identical syntax, I could use that as the base for my GML interpreter, and you could combine your JScript or VBScript with GML function calls. It would be less popular because the syntax is much different in VBScript than JScript, but you could easily write your interpreted GML with VBScript syntax as well.
     
  21. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    Not exactly.

    They changed the way the renderer handles the scenegraph in 2.x. It doesn't play as nicely as it did in 1.4.

    Rendering a simple quad is quite a turd now.

    I can elaborate if anyone is really interested.

    And as a side note windw_device() won't return the address of the OpenGL renderer, it is a Windows only function.
     
  22. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    on OpenGL there is a global context you don't need to get the handle in the same way so it is not needed..

    We changed to DX11 for rendering in GMS2 on Windows in some ways this is easier (than DX9) in others it is more difficult - plenty of examples out there to show you how to do things though - if you are using an extension to draw a quad then you are doing it wrong... most of your rendering needs can be handled with vertex buffers and freezing them or calling an extension function to build a buffer and convert it to a vertex buffer in GML code.

    Russell
     
  23. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    LOL @rwkay - how else would you render fully interactive vdeo inside GMS, Russ? ;)

    You guys haven't managed it yet :D
     
  24. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    not sure what you are meaning at all?????

    We have plenty examples of rendering full 3D interactively without any extension required.

    Russell
     
  25. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    Sorry @rwkay I left out the key word in my reply 'video'. I have re-edited my post.
     
  26. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
  27. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    I understand this. I was the first person on the planet to bring Video to the renderer, having it behave exactly as a sprite, preserving depth, and any other things you want to throw at it.

    That starts out with a simple quad.

    I am saying that the changes in GMS2 is much more difficult due to the way you have changed the scene graph.
     
  28. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    But you see that is the ironic thing.... we did not change the scene graph... the layer system was always effectively there... just much more CPU intensive before.. the scene graph is exactly the same... so confused what has made it more complicated for you (apart from being DX11)

    Russell
     
  29. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    Ok I'll explain in case you are not aware of what is currently happening.

    Pseudo code

    Code:
    // What we want to happen
    
    set_shader(something)
    draw_sprite()
    draw_quad_dll()
    draw_sprite()
    shader_reset()
    
    Vs

    Code:
    // What now happens in GMS2 verifiable using Pix or VS Graphical debugger
    
    set_shader(something)
    draw_sprite()
    draw_sprite()
    shader_reset()
    
    draw_quad_dll()
    
    In GMS1.4 the first code example would stay true. But in GMS2 the call to the DLL is pushed out of order to after the shader_reset() call.

    Which has all sorts of implications. Draw order is now incorrect when using painters algorithm and the quad no longer gets the benefits of the shader, meaning you have to have a precompiled HLSL shader inside the DLL.

    Doesn't matter where you make the call to the DLL, it could be before any Sprite draw call, it will get pushed to the end.

    As I said, makes it a turd to do anything now.

    I can make a simple project and send to you if you want to see this for yourself.
     
  30. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    I suspect that the issue you are seeing is because you have not informed us that you have changed state in the middle there... and the second draw_sprite() is not breaking the batch... just add in a draw_flush() - https://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/drawing/draw_flush.html before the draw_quad_dll() to inform us that you want us to submit everything to the GPU up to that point, so that your rendering will interleave.

    This has not changed going from GMS1 -> GMS2 but you may have been getting away with it before, and other drivers / gpu types (that you did not test with) may have had the same behaviour as GMS2

    Russell
     
    Binsk and Lonewolff like this.
  31. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    Interesting. I'll take a look tomorrow and see if that works.

    Having said that though, I do know that if you do this;

    Code:
    Shader_set
    Draw_quad
    Shader_reset
    ...the drawing of the quad will still be pushed outside of the shader_set / reset scope.

    But again, I'll do some further testing and let you know :)
     
  32. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    the draw_flush will submit everything from the GML side to the GPU before you submit anything so ordering will be preserved (it is what we do internally) - this means that any batching will be broken, but the draw order will be correct.

    Russell
     
    Lonewolff likes this.
  33. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    @rwkay - Just tried out the draw flush suggestion. Still the same behaviour. The draw call from the DLL gets pushed outside of the draw event.

    [​IMG]
     
  34. rwkay

    rwkay YoYo Games Staff YYG Staff

    Joined:
    Apr 12, 2016
    Posts:
    1,048
    Please file a bug with a simple example (include the source to the extension) and we will take a look, I think you are doing something wrong there, but without seeing your code it will be difficult to tell.

    Russell
     
    Lonewolff likes this.
  35. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    No worries, will do :)
     
  36. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,142
    @rwkay - FWIW, this is presently the entirety of the dll call in the draw event (if this sheds any light)

    Code:
    fn_export double mesh_draw()
    {
        struct Float2
        {
            float x, y;
        };
    
        unsigned int stride = sizeof(Float2);
        unsigned int offset = 0;
        d3dContext->IASetInputLayout(d3dInputLayoutXY);
        d3dContext->IASetVertexBuffers(0, 1, &bufferMesh, &stride, &offset);
        d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
        d3dContext->Draw(3, 0);        // One triangle
    
        return 1;
    }
    
    So there is nothing really magical going on.

    It draws a triangle fine, but not when it should be (as depicted in the render capture above).
     
  37. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    At the very least, we should have a way to get the function address for window_handle() - that way, we can access the window's handle on Windows, Mac, and Linux without needing to waste our function's arguments on that. Keep in mind - we only get to use up to 4 arguments when any one of them is a char * or pointer. So that is one of the biggest reasons this would be useful, other than the fact we need it to make our extensions more user-friendly. A lot of users who don't make extensions but do use them won't understand why there are functions that require an argument to be window_handle(), it just looks bad.
     
  38. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,360
    just hide it in your own function?
    I sometimes end up making internal version and public version of scripts to call weird stuff.
    Often its because I have to pass data around on a buffer.
     
  39. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    How do you make a script internal or public? I thought that was only possible in pre-studio extensions, and now they were all public?
     
  40. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,360
    They where always all public. I just add internal, or a couple underscores in front.
    Not super neat but hey, GML never ends up neat...
     
    Samuel Venable likes this.
  41. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    Oh ok, I gotcha. But I do remember in the GM7 extension maker you could include scripts that don't show up anywhere in the IDE, except the code editor's intellisense. Then again if it shows up anywhere it's still considered public so I see what you mean. The major thing is I just don't want certain scripts to be view-able from the resource tree, like GM 8.1 and below extensions worked.
     
  42. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,360
    eh, thats not how GM works! Its all about making averything horible and clogging your resource tree, and your intelisense :p
     
    Samuel Venable likes this.
  43. kburkhart84

    kburkhart84 Firehammer Games

    Joined:
    Jun 26, 2016
    Posts:
    463
    Just FYI, The issue with internal scripts I've seen it handled(and do it myself) by just making it a separate folder inside your asset's folder. If you type the underscores it will still show up in intellisense though. But I generally get around that too. My FHInput extension for example, all scripts that you should be calling start with fhinput**** and then any internal scripts start with _fhinput*** so you can easily filter the scripts in intellisense by typing fhinput, and then if other assets or the user have scripts that start with underscore, then my fhinput scripts will be filtered out of intellisense will be filtered away as soon as they start typing once a letter differs from "_fhinput." This isn't the perfect solution, as something done directly by Yoyo to hide those scripts could be better. But since it is generally a good idea for many of us to allow the internal source to be seen/edited anyway, it isn't bad.
     
    Samuel Venable likes this.
  44. YellowAfterlife

    YellowAfterlife ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    2,351
    y'all might be too busy complaining about things

    You set a script/function's help to be an empty string and that hides it from auto-completion.
    In GMS2 there is currently a bug where this (and "hidden" option in JSON) is ignored and scripts/functions are still shown in auto-completion (albeit without argument info).

    With window_handle in particular, you can send it to extension during initialization, and then use that handle - I don't think there's any scenario where game window handle could suddenly change.
     
    Samuel Venable likes this.
  45. Samuel Venable

    Samuel Venable Time Killer

    Joined:
    Sep 13, 2016
    Posts:
    1,217
    Yeah, I'll do that if I ever need it. I was actually thinking this would be useful to some users who aren't in my position - for whatever reason I can't upload to the marketplace actual "extensions" and by that I mean there is a bug where if I try to upload the "Extensions" resource folder, in GMS 1.4 it acts as though it uploads OK, but when I download my extension from the MP to see if everything uploaded correctly the only thing that never actually downloads is the Extensions resource folder files, so to make it consistent between my GMS 1.4 and 2 versions of my assets, I use scripts and included files instead, which I'm cool with. Half the time I need extra GML put in with my native code so I need it as a script and not a directly called function from the extensions folder anyway. Anyway that's why I never filed a bug for it. It's not a huge deal to me.

    Again, thanks for your suggestion, that is very useful info for people who didn't already know that, and I am one of those people. I'll probably do that once GMS 1.4 assets officially die off the MP, if that ever happens.
     
  46. kburkhart84

    kburkhart84 Firehammer Games

    Joined:
    Jun 26, 2016
    Posts:
    463
    Way back when I had made an extension for GM8 that would do bit by bit loading of external sprites, sounds, etc.. from zip files, and then automatically unloading those resources later(similar to what you do with texture pages now if you so desire). It was using a DLL. I only had scripts actually call the DLL functions, wrapping all of that in GML instead of asking the user to use the "external_call" functions. This made it much easier to add stuff to the GML as needed. I wouldn't ever have the user calling DLL functions directly, though I haven't done anything with a DLL recently.
     
    Samuel Venable likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice