Valhalla Legends Forums Archive | C/C++ Programming | Need some help passing arguments with function pointer (brood war)

AuthorMessageTime
warz
Hey, I'm working on updating my dll, and it looks like they've changed the way that the local print text function is being called. I know that with fast call the first function argument, and the second function argument turn out to be ECX and EDX. Here's my function pointer...

[code]
typedef void (__fastcall *fpPrintText) (int x, const char *edx, const char *eax);
[/code]

When Brood War calls this function, the registers look like so...

[quote]
EAX: address of text
ECX: coordinate (?)
EDX: address of text again
EBX: chat buffer slot # (?)
EDI: coordinate (?)
[/quote]

These are the five registers this function appears to use when writing text. I don't plan on writing text over the in-game chat area, so I don't know if this requires five arguments, but this is just what I saw while watching it operate.

As you can see, my function pointer's first arguments is 'int x', which rightfully becomes ECX, and the second argument is 'edx', which rightfully becomes EDX or the actual text being printed, the third argument is EAX, which becomes the correct EAX in the function, which is also the text being printed.

My question is though, how do I pass the rest of these arguments? I tried adding onto my function definition, just creating four arguments, and it looks like it puts it on the stack and tries to grab from there - but it crashes. This is not how Brood War operates. Does anyone know how to properly pass a EBX and EDI parameter to this function, in C++?
October 9, 2006, 6:57 AM
warz
Well, I don't know if there's a different way, but I just use inline assembler to explicitly move the values into the desired registers,
October 9, 2006, 2:40 PM
Arta
Can you provide an address in bsnp for one of these calls so I can have a look?
October 13, 2006, 9:11 AM
Kp
If warz is correct, Blizzard may have turned on inter-function optimizations, allowing the compiler to use a non-standard calling convention to minimize stack usage.  In such a case, inline assembly is probably the only option.  You could avoid some of the pain of inline assembly for repeated calls by creating a C wrapper with a normal interface and having it do the inline assembly to set up the registers in the necessary way.
October 14, 2006, 5:06 PM

Search