Jump to content


Relinquished

Member Since 11 Dec 2005
Offline Last Active Jun 09 2010 04:01 PM

Topics I've Started

Make Dll From Asm For Gamemaker

06 October 2008 - 01:26 AM

Alright, i haven't seen a ASM DLL tutorial anywhere here so I'll do one.

Posted Image
Posted Image

This example illustrates how to make a DLL in assesmbly language and uses in Gamemaker.

Below is everything you need to compile this example including the example too.

Download Example:
Posted Image

Download MinGW:
MinGW
if that doesn't work try this: Link Be sure to choose the "Automated" Installer.



Okay, this example will use Nasm to assemble the assembly source into an object file and will use MinGW compiler set to link everything into a DLL.
Below in small print is the explaination of the assembly example.  Read it if you want to know how to use assembly with game maker.


Alright, let's go through the source.
SEGMENT code Use32
What this directive does is make all the code after this line be assigned to the "code" segment.  Segments allow object files and executives have separate parts in their code and data so that everything isn't in one place at once.  And if that we're to happen, code would unintentionally be executing data and it's practically a nightmare after that.  Use32 makes the generate machine code 32-bit, so and addressing mode specifiers in the opcode is made 32-bit instead of 16.  Which I think 16-bit is the default.  But you don't need to know about the opcode bytes in this case.
global _DllMain
global _myfunc
These two lines make the symbols _DllMain and _myfunc global.  It's like in game maker, other objects can see global variables but not local.  And this source file is the game object in this case.  So since these two symbols are global, the scope of these two symbols will remain visible to other objects and the linker.  Though sometimes when referencing a global symbol you have to use the extern keyword to tell the assembler that there is an external symbol.  Why these are global are for two reasons, one is _DllMain needs to be global so the compiler can acknowledge it and use it as an entry point, where as all Dll's have the common entry point of "DllMain".  And second _myfunc is the test function that the GM example will use and definitely needs to be global so that the linker can find the location of the symbols when trying to export.

_myfunc:
		push ebp
		mov ebp, esp

			fld qword [ebp + 8];Load/Push the argument onto the FPU register stack
		fadd st0, st0;//Add it by itself or multiply by 2

;mov esp, ebp; Would need this line if we messed with stack pointer
		pop ebp
		ret
Here is the code that follows after the defined _myfunc symbol and ends at the procedure's return instruction.  The first two instructions establishes a stack frame by saving the stack frame pointer ebp by pushing it onto the stack and moves ebp values to the stack pointer register's value.  If this routine had local variables, then ESP(Stack pointer register) would have been subtracted to dynamically allocate space for these variables.  Esp is subtracted because the stack grows down to lower addresses.

The next two lines are the two FPU instructions that add the given argument by itself thus making a multiplication by two.  The first one is "fld", its an instruction that pushes the given operand onto the register stack.  when dealing with double's or floats, these are floating point data types that are different than integers because they have extra information that gives the decimal place of the number.  A double is called double because it is twice of a float, or a single precision float point unit, hence double-precision.  Certain fields of bits in these FPU data types are the exponential part, which gives it it's decimal place.  The FPU is a coprocessor that has it's own enviroment on the CPU, it's a co-processor because of the sheer amount of work it would take the CPU to do these float points or fractional calculations without the loss of speed.  So "stack" is used to perform algebraic operations.  There are 7 64-bit registers that act as the FPU stack.  I won't get into more of this but all you need to know is that the instruction takes the argument given by the GM code and pushes it onto the top of the stack.  The next two instructions adds the top of the register stack by it's self thus multiplying it by two.  And the ret instruction simply restores the instruction pointer thus returning back to the caller.

And the rest you can see in the comments is explained.

When exporting, a .def file is used to list all the symbols to be external.  You can find more about those on google.

I made a slight mistake in the code, when stdcall is used, the dll is suppose to clean up the arguments passed.  But game maker obviously has a calling facility that checks the stack pointer register before the call to the enternal routine and saves it and restores it when coming back from the external procedure.  So I'm glad mark added that.

So yeah, when writing procedures in ASM, be sure to globalize them and add a "_" suffix to the real name of the symbol that you want exported.  And in the export definition file(.def file) specify the name of the symbol without the add underscore prefix. And then to make the DLL, compile the dll with the already compiled assembly object files, and you can also mix C/C++ code in there too.  And don't forget to pass the definition file to the compiler also.


And that's about it, to compile it you must use MinGW.  MinGW is a set of exe's that act as compilation tools.  And they will make your source from your assembly code into a DLL.
When using doubles in gamemaker always use FPU instructions in assembly when handling these values.

Plain Soldier Sprites

01 August 2008 - 10:23 PM

Can anybody direct my on how to acquire side scrolling plain soldier sprites?  Or at least how to make them?

Quick Question About Model Animations.

22 July 2008 - 10:41 PM

In commercial 3D games, how do they make models get into stuff like vehicles?  Using static animations or using a joint system that puts a model into a join tween.  I have no clue how one would approach this.  So am I better off making models having static animations?

Gamemaker.nl Games

18 July 2008 - 12:27 AM

If anybody still remembers the old site,  there we're some games there that we're stand alones and I seemed to forgot all there names.  I would really like to play those games again, can anybody show me where I can download them or the names?

Drawing A Rgba Surface Atop A Rgba Surface

05 July 2008 - 02:42 AM

okay, I'm trying to draw a surface that has a sprite that has been alpha-masked onto a surface that in-fact already has a alpha-based sprite on that one too.
It's not working out.  I've even written a little scanner where i can use the arrow keys to go through every possible blend mode(121 total) and still no avail.
It does the clear out alpha thing, it's aggravating!  i gotta have this solved or else I will lose all motivation, and that would be a bloody shame :)

So has anyone solved this? I've searched the forums but no-one has attempted what I'm doing because stuff like lighting engines just draw onto one surface mostly.
If this doesn't work out, I'll have to stick with the strange effects I get with other stuff.

I'm making a window for my gui and rendering the text for the title is not working out so gewd.
Here\'s a pic of what I succesfully coded so far:
Posted Image
And here\'s the problem, the text isn't rendering correctly(as the title text):
[removed text cause I got pass my image limit]
The text is on a surface so that if the window is resized and is too small, the title text can be drawn partially using the neat draw_surface_part function.  It\'s also a surface because I wanted a make a vista
glow text effect for the title. So I knows theres gotta be some combination of letters and numbers that can make render to surface happen!

Here's an editable I made that can replicate this problem(it's a different but the idea is the same):
Posted Image
Posted Image
I've made the the gradient in this example completely the same as the mask.  As you can see, the ball is rendered correctly in the top right corner.
There are also two more balls in the center.  These were rendered onto a surface, where each ball had it's own surface who's dimensions are the same as the sprite.  And the two surfaces are drawn onto a larger surface
which the larger surface is drawn.  The balls on the bottom are the two surfaces of each ball rendered directly onto the screen.  There still small as it is.  So whats the problem?