16bit values in IDoMethod()

This forum is for general developer support questions.
Post Reply
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

16bit values in IDoMethod()

Post by gonegahgah »

I just changed my code over to using IDoMethod() instead of IDoMethodA().
I notice the 16 bit X,Y values are coming through as 32 bit values.
The result is that X is coming through as 0 and Y is coming through as the X value in the passed msg.

eg.
struct ZM_FOLLOWMOUSE
{
..ULONG MethodID;
..struct Screen *zpfm_Screen;
..char *zpfm_PubScreenName;
..struct
..{
....int16 ScreenX;
....int16 ScreenY;
..} zpfm_Mouse;
..struct Window *zpfm_Window;
}

struct Screen *pScreen;
struct Window *pWindow;
int16 iScreenMouseX, iScreenMouseY;
cb->cb_IIntuition->IDoMethod(pFeeder, ZM_FOLLOWMOUSE, pScreen,
cb->cb_PubScreenName, iScreenMouseX, iScreenMouseY, pWindow);

Is there a way to do this correctly. Or should I go just back to using IDoMethodA().
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1479
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: 16bit values in IDoMethod()

Post by tonyw »

In general, all args passed to Amiga functions are passed as 32-bit values. So if you want to retrieve a 16-bit value, you must provide a 32-bit location where it can be stored by the function. This means that struct IBox and other 16-bit variables can not be used directly. You can pass 16-bit values, since the compiler will expand them to 32-bits, but getting them back means that you have to store them in a 32-bit variable, then read off the lower 16 bits of the returned value.
cheers
tony
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: 16bit values in IDoMethod()

Post by gonegahgah »

Cool, thanks Tony. I'll go back to using IDoMethodA().

You would think there would be some way to pass 16bit values on the stack via a function call.
Certainly the tag item functions need to pass everything as 32bit aligned but functions like IDoMethodA would be better to align on the arg types bit length.

I haven't looked enough into how to properly create a vararg function yet. Maybe it will make more sense to me then...
User avatar
tonyw
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 1479
Joined: Wed Mar 09, 2011 1:36 pm
Location: Sydney, Australia

Re: 16bit values in IDoMethod()

Post by tonyw »

You would think there would be some way to pass 16bit values on the stack via a function call.
You can do it, but they have to occupy a full 32-bit longword for each arg, even if the high 16 bits are all zero.
cheers
tony
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: 16bit values in IDoMethod()

Post by gonegahgah »

tonyw wrote:You can do it, but they have to occupy a full 32-bit longword for each arg, even if the high 16 bits are all zero.
Just wondering...
When printf (and its many equivalents) pass arguments on the stack, do they align them all to 32 bit?
I know they use %d and %ld to differentiate. Would they need to differentiate if the arguments were all 32 bit aligned anyway?
User avatar
salass00
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 530
Joined: Sat Jun 18, 2011 3:12 pm
Location: Finland
Contact:

Re: 16bit values in IDoMethod()

Post by salass00 »

You could also just do:

Code: Select all

cb->cb_IIntuition->IDoMethod(pFeeder, ZM_FOLLOWMOUSE, pScreen, 
cb->cb_PubScreenName, (iScreenMouseX << 16)|(iScreenMouseY), pWindow);
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: 16bit values in IDoMethod()

Post by gonegahgah »

Thanks again salass.

That looks like it would work.

Even though their are no plans in the direction, I thought I read somewhere that we have to be careful with ended-ness when we code.
Does that solution present any problems in that respect or is it perfectly alternate future safe?
User avatar
salass00
AmigaOS Core Developer
AmigaOS Core Developer
Posts: 530
Joined: Sat Jun 18, 2011 3:12 pm
Location: Finland
Contact:

Re: 16bit values in IDoMethod()

Post by salass00 »

gonegahgah wrote: Even though their are no plans in the direction, I thought I read somewhere that we have to be careful with ended-ness when we code.
Does that solution present any problems in that respect or is it perfectly alternate future safe?
It assumes a big endian CPU.

For a little endian CPU (like x86) you would have to do:

Code: Select all

cb->cb_IIntuition->IDoMethod(pFeeder, ZM_FOLLOWMOUSE, pScreen, 
cb->cb_PubScreenName, (iScreenMouseX)|(iScreenMouseY << 16), pWindow);
This is because of the different byte ordering used (most significant byte first vs least significant byte first).
User avatar
gonegahgah
Posts: 43
Joined: Fri May 31, 2013 4:22 pm

Re: 16bit values in IDoMethod()

Post by gonegahgah »

Cool. I'll probably avoid using that then.
Post Reply