Mouse routines are implemented in <lua_maus.c>. Header file is: <lua_maus.h>.

Most of mouse routines are ready.

Some of these routines are implemented different way than their Allegro counterparts.

 

Mouse routines


result = mouse.install( )

Installs the Allegro mouse handler. You must do this before using any other mouse functions.

Return value: Returns boolean value: true if the mouse handler has successfully been installed (ie. this is the first time a handler is installed or you have removed the previous one), false on failure or when mouse is already installed.

I have corrected a bug in mouse.install( ) implementation: Corrected version should look like this: 

 

   
static int l_install_mouse(lua_State* L)
{
lua_pushboolean(L, (install_mouse()>0) );
return 1;
}
   
   

 

mouse.remove( )

Removes the mouse handler. You don't normally need to bother calling this, because allegro_exit() will do it for you. Function does not return any value.

 

result = mouse.poll( )

Wherever possible, Allegro will read the mouse input asynchronously (ie. from inside an interrupt handler), but on some platforms that may not be possible, in which case you must call this routine at regular intervals to update the mouse state variables. To help you test your mouse polling code even if you are programming on a platform that doesn't require it, after the first time that you call this function Allegro will switch into polling mode, so from that point onwards you will have to call this routine in order to get any mouse input at all, regardless of whether the current driver actually needs to be polled or not.

Return value: Returns true on success, or false on failure (ie. no mouse driver installed).

 

result = mouse.needs_poll( )

Returns true if the current mouse driver is operating in polling mode, false otherwise.

 

mouse.enable_hardware_cursor(bool enable);

There is no reason to bloat LuAllegro with many functions when their number can be reduced. mouse.enable_hardware_cursor replaces two of Allegro functions: enable_hardware_cursor and disable_hardware_cursor

Here is an implementation:

static int l_enable_hardware_cursor(lua_State* L)
{
int enable=lua_toboolean(L,1);

if (enable)
enable_hardware_cursor();
else
disable_hardware_cursor();

return 0;
}

mouse.select_mouse_cursor(int cursor);

This function allows you to use the operating system's native mouse cursors rather than some custom cursor. You will need to enable this functionality by calling mouse.enable_hardware_cursor(true) beforehand. If the operating system does not support this functionality, or if it has not been enabled, then Allegro will substitute its own cursor images. You can change these substitute images using set_mouse_cursor_bitmap( ).

Note that the effects of this function are not apparent until mouse.show( ) is called.

To know whether the operating system's native cursor is being used, or if Allegro has made a substitution, you can check the GFX_SYSTEM_CURSOR flag in gfx_capabilities after calling show_mouse().

These constants are not present in LuAllegro yet:

MOUSE_CURSOR_NONE
Selects an invisible mouse cursor. In that sense, it is similar to calling show_mouse(NULL);

MOUSE_CURSOR_ALLEGRO
Selects the custom Allegro cursor, i.e. the one that you set with set_mouse_sprite().

MOUSE_CURSOR_ARROW
The operating system default arrow cursor.

MOUSE_CURSOR_BUSY
The operating system default `busy' cursor (hourglass).

MOUSE_CURSOR_QUESTION
The operating system default `question' cursor (arrow with question mark).

MOUSE_CURSOR_EDIT
The operating system default `edit' cursor (vertical bar).

Example:

   -- initialize mouse sub-system 
   mouse.install();
   mouse.enable_hardware_cursor(true);
   
   -- Set busy pointer 
   mouse.select_cursor(MOUSE_CURSOR_BUSY);
   mouse.show_mouse(screen);
   
   -- Initialize stuff 
   ...
   
   --Set normal arrow pointer 
   mouse.select_cursor(MOUSE_CURSOR_ARROW);
Function set_mouse_cursor_bitmap has not been implemented

void set_mouse_cursor_bitmap(int cursor, BITMAP *bmp);


This function changes the cursor image Allegro uses if select_mouse_cursor() is called but no native operating system cursor can be used, e.g. because you did not call enable_hardware_cursor().

The cursor argument can be one of:
MOUSE_CURSOR_ALLEGRO
MOUSE_CURSOR_ARROW
MOUSE_CURSOR_BUSY
MOUSE_CURSOR_QUESTION
MOUSE_CURSOR_EDIT

but not MOUSE_CURSOR_NONE.

The bmp argument can either point to a bitmap userdata or it can be nil. Passing a bitmap makes Allegro use that image in place of its own default substition (should the operating system's native cursor be unavailable). The bitmap must remain available for the duration in which it could be used. Passing nil lets Allegro revert to its default substitutions.

The effect of this function will not be apparent until mouse.show( ) is called.

 

x , y , z , right_button , left_button , middle_button = mouse.position( )

Instead of having five or six functions to read mouse position and buttons we have ony one: mouse.position( ) , which reads global Allegro variables:

extern volatile int mouse_x;

extern volatile int mouse_y;

extern volatile int mouse_z;

extern volatile int mouse_b;

extern volatile int mouse_pos;

Here is an implementation:

//--------------------------------------------------------------------
static int l_mouse_position(lua_State* L)
{
lua_pushnumber(L,mouse_x);
lua_pushnumber(L,mouse_y);
lua_pushnumber(L,mouse_z);
lua_pushboolean(L,(mouse_b&1));
lua_pushboolean(L,(mouse_b&2));
lua_pushboolean(L,(mouse_b&4));
return 6;
}
 
 

 

mouse.show(bitmap_userdata bmp);

Tells Allegro to display a mouse pointer on the screen. This will only work if the timer module has been installed. The mouse pointer will be drawn onto the specified bitmap, which should normally be `screen' - nil in LuAllegro (see later for information about bitmaps). 

To hide the mouse pointer, use mouse.hide( ) function.

Warning: if you draw anything onto the screen while the pointer is visible, a mouse movement interrupt could occur in the middle of your drawing operation. If this happens the mouse buffering and graphics drawing code will get confused and will leave 'mouse droppings' all over the screen. To prevent this, you must make sure you turn off the mouse pointer whenever you draw onto the screen. This is not needed if you are using a hardware cursor.

 

mouse.hide( )

To hide the mouse pointer, use mouse.hide( ) function.

 

 

mouse.scare( )

Helper for hiding the mouse pointer prior to a drawing operation. This will temporarily get rid of the pointer, but only if that is really required (ie. the mouse is visible, and is displayed on the physical screen rather than some other memory surface, and it is not a hardware or OS cursor). The previous mouse state is stored for subsequent calls to unscare_mouse().

 

This function is not implemented yet.

void scare_mouse_area(int x, int y, int w, int h);


Like mouse.scare( ), but will only hide the cursor if it is inside the specified rectangle. Otherwise the cursor will simply be frozen in place until you call mouse.unscare( ), so it cannot interfere with your drawing.

 

mouse.unscare( )

Undoes the effect of a previous call to mouse.scare( ) or mouse.scare_area( ), restoring the original pointer state.

 

result = mouse.show_os_cursor(cursor);

In case you do not need Allegro's mouse cursor API, which automatically emulates a cursor in software if no other cursor is available, you can use this low level function to try to display or hide the system cursor directly. The cursor parameter takes the same values as select_mouse_cursor. This function is very similar to calling enable_hardware_cursor, select_mouse_cursor and show_mouse, but will not try to do anything if no system cursor is available.

The most common use for this function is to just call it once at the beginning of the program to tell it to display the system cursor inside the Allegro window. The return value can be used to see if this suceeded or not. On some systems (e.g. DirectX fullscreen) this is not supported and the function will always fail, and in other cases only some of the cursors will work, or in the case of MOUSE_CURSOR_ALLEGRO, only certain bitmap sizes may be supported.

You never should use show_os_cursor together with the function show_mouse and other functions affecting it (select_mouse_cursor, enable_hardware_cursor, disable_hardware_cursor, scare_mouse, unscare_mouse). They implement the standard high level mouse API, and don't work together with this low level function.

Return value: Returns true if a system cursor is being displayed after the function returns, or false otherwise.

This variable has not been implemented as LuAllegro function yet.

extern volatile int freeze_mouse_flag;


If this flag is set, the mouse pointer won't be redrawn when the mouse moves. This can avoid the need to hide the pointer every time you draw to the screen, as long as you make sure your drawing doesn't overlap with the current pointer position.

 

mouse.set_position(x,y,z)


This function replaces two Allegro functions: position_mouse and position_mouse_z

Sets mouse position to the specified x and y coordinates. Z coordinate is optional, but will also be set when provided.

Here is an implementation:

//void position_mouse(int x, int y);
//void position_mouse_z(int z);
static int l_mouse_set_position(lua_State* L)
{
int x,y;
if (lua_type(L,1)==LUA_TNUMBER)
   {
   x=lua_tonumber(L,1);
   y=lua_tonumber(L,2);
   position_mouse(x,y);
   }
if (lua_type(L,3)==LUA_TNUMBER)
   {
   position_mouse_z( (int) lua_tonumber(L,3));
   }
return 0;
}

 

 

mouse.set_range(x1, y1, x2, y2)

Sets the area of the screen within which the mouse can move. Pass the top left corner and the bottom right corner (inclusive). If you don't call this function the range defaults to (0, 0, SCREEN_W-1, SCREEN_H-1).

 

mouse.set_speed( xspeed , yspeed )

Sets the mouse speed. Larger values of xspeed and yspeed represent slower mouse movement: the default for both is 2.

 

mouse.set_sprite(bitmap_userdata sprite);


You don't like Allegro's mouse pointer? No problem. Use this function to supply an alternative of your own. If you change the pointer and then want to get Allegro's lovely arrow back again, call mouse.set_sprite(nil)

Sprite argument passed to mouse.set_sprite function should either be bitmap userdata or nil. 

To create bitmap userdata look at the "Bitmap Objects" chapter.

 

As a bonus, mouse.set_sprite(nil) uses the current palette in choosing colors for the arrow. So if your arrow mouse sprite looks ugly after changing the palette, call mouse.set_sprite(nil)

 

I can see that there is a small bug in current set_mouse_sprite function

In case you pass nil to the function mouse.set_sprite then set_mouse_sprite(NULL) should be called inside, but it won't be. 

A small "else set_mouse_sprite(NULL);" inserted just in line above "return 0;" would fix the problem.

 

//------------------------------------------------
//void set_mouse_sprite(BITMAP *sprite);
static int l_set_mouse_sprite(lua_State* L)
{
AUD* b = (AUD*) lua_touserdata(L,1);

if ((b) && (b->DataType==AL_BITMAP) && (b->DataPtr))
set_mouse_sprite( (BITMAP*) b->DataPtr);

return 0;
}

It looks like writing documentation while reading source code helps correcting some bugs.

 

Function set_mouse_sprite_focus is not implemented yet.

void set_mouse_sprite_focus(int x, int y);


The mouse focus is the bit of the pointer that represents the actual mouse position, ie. the (mouse_x, mouse_y) position. By default this is the top left corner of the arrow, but if you are using a different mouse pointer you might need to alter it.

 

mickeyx , mickeyy = mouse.get_mickeys( )

Measures how far the mouse has moved since the last call to this function. The values of mickeyx and mickeyy will become negative if the mouse is moved left or up, respectively. The mouse will continue to generate movement mickeys even when it reaches the edge of the screen, so this form of input can be useful for games that require an infinite range of mouse movement.

Note that the infinite movement may not work in windowed mode, since under some platforms the mouse would leave the window, and may not work at all if the hardware cursor is in use.

 

Mouse callback is not implemented and I am not sure it ever will be, since it happens asynchronously in the interrupt. It is possible to write useful programs without the need of using interrupt callbacks anyway. This callback exists in Allegro library because it is a game programming library, so I can imagine that these low-level tricks are desired by game programmers.

extern void (*mouse_callback)(int flags);


Called by the interrupt handler whenever the mouse moves or one of the buttons changes state. This function must be in locked memory, and must execute _very_ quickly! 

The statement above is another argument, that mouse_callback should never be implemented in LuAllegro. 

It is passed the event flags that triggered the call, which is a bitmask containing any of the values MOUSE_FLAG_MOVE, MOUSE_FLAG_LEFT_DOWN, MOUSE_FLAG_LEFT_UP, MOUSE_FLAG_RIGHT_DOWN, MOUSE_FLAG_RIGHT_UP, MOUSE_FLAG_MIDDLE_DOWN, MOUSE_FLAG_MIDDLE_UP, and MOUSE_FLAG_MOVE_Z. Note that even if the mouse has more than three buttons, only the first three can be trapped using a callback.


Back to main page