How to use the Logitech G15 gamers keyboard with MUSHclient

Posted by Nick Gammon on Fri 16 Jun 2006 05:39 AM — 43 posts, 226,238 views.

Australia Forum Administrator #0

Recently I purchased a Logitech G15 "gamers" keyboard. This is what it looks like:

One of the interesting things about it is the set of additional 18 "soft keys" on the left-hand side of the keyboard, plus the keys M1/M2/M3 which let you select the 18 soft-keys into one of 3 "banks". This effectively gives you 54 additional keys that you can program.

You can program the keys to either emulate an existing key (eg. Shift+Ctrl+Alt+T) which would be handy for binding functions to some obscure keystroke combination (using the Accelerator function in MUSHclient) and then call that up with a single keypress.

You can also record a sequence of presses using either the MR (macro record) key, or the supplied software. The sequence can include emulated mouse clicks, and delays, the duration of which you can customize.

The final point of interest is the fold-up LCD screen. This can be programmed from the PC. There are some supplied apps that show things like the time of day, or the CPU usage. However the challenging part is to make the display show game-based information, as in the screenshot below:

(My photo doesn't do it full justice, it is hard to photograph LCD screens properly).

The follow-up posts describe how you can interface the keyboard with MUSHclient and customize the display to show whatever you want.

Australia Forum Administrator #1
To connect to the LCD screen I used the SDK (software development kit) that Logitech conveniently supplied on the CD that came with the keyboard. However, I upgraded the keyboard software from their web site and also get an upgraded SDK.

To interface with MUSHclient I wrote a "wrapper" DLL that lets you use most of its functionality from Lua script calls.

First, download the DLL from here (66 Kb):

http://www.gammon.com.au/files/mushclient/G15_Display.zip

If you are using MUSHclient version 3.80 onwards, use this version instead:

http://www.gammon.com.au/files/mushclient/lua5.1_extras/G15_Display.zip

Then, extract it and place the G15_Display.dll into the same directory as the MUSHclient.exe program.

Then you need to install the DLL. I did it as part of a trigger:


if not g15 then
  assert (loadlib ("G15_Display.dll", "luaopen_g15")) ()
  g15.SetAsForeground (true)
end -- if


This effectively installs it on-the-fly the first time it is needed.

If you are using MUSHclient 3.80 onwards you need to change loadlib to package.loadlib.

Then I made a trigger that captures the prompt line and sends the information in it to the LCD screen as both numbers and a progress bar:


<triggers>
  <trigger
   enabled="y"

match="^\&lt;(?P&lt;health&gt;\d+)\/(?P&lt;maxhealth&gt;\d+)hp (?P&lt;mana&gt;\d+)\/(?P&lt;maxmana&gt;\d+)m (?P&lt;move&gt;\d+)\/(?P&lt;maxmove&gt;\d+)mv (?P&lt;xp&gt;\d+)\/(?P&lt;xptolevel&gt;\d+)xp\&gt;"


   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>if not g15 then
  assert (loadlib ("G15_Display.dll", "luaopen_g15")) ()
  g15.SetAsForeground (true)
end -- if

if not g15.IsConnected () then
  return
end -- if

if not hp_text then
  hp_text = g15.AddText ("static", "small", "right", 40, 0, 0)
  hp_bar  = g15.AddProgressBar ("filled", 100, 8, 50, 0) 
  mana_text = g15.AddText ("static", "small", "right", 40, 0, 10)
  mana_bar  = g15.AddProgressBar ("filled", 100, 8, 50, 10) 
  move_text = g15.AddText ("static", "small", "right", 40, 0, 20)
  move_bar  = g15.AddProgressBar ("filled", 100, 8, 50, 20) 
end -- if

hp_text:set ("hp: %&lt;health&gt;")
hp_bar:percent (%&lt;health&gt; / %&lt;maxhealth&gt; * 100)

mana_text:set ("m: %&lt;mana&gt;")
mana_bar:percent (%&lt;mana&gt; / %&lt;maxmana&gt; * 100)

move_text:set ("mv: %&lt;move&gt;")
move_bar:percent (%&lt;move&gt; / %&lt;maxmove&gt; * 100)
</send>
  </trigger>
</triggers>


This trigger adds 6 things to the LCD (spaced 10 pixels apart vertically for hp/mana/movement). There are 3 text boxes for the text display, and 3 progress bars for a visual progress indication.

Then this trigger handles exits when they appear:


<triggers>
  <trigger
   enabled="y"
   match="Exits: *"
   send_to="12"
   sequence="100"
  >
  <send>if not g15 then
  assert (loadlib ("G15_Display.dll", "luaopen_g15")) ()
  g15.SetAsForeground (true)
end -- if

if not g15.IsConnected () then
  return
end -- if

if not exits_text then
  exits_text = g15.AddText ("static", "small", "left", 160, 0, 30)
end -- if

exits_text:set ("%0")
</send>
  </trigger>
</triggers>

Amended on Tue 06 Mar 2007 06:46 AM by Nick Gammon
Australia Forum Administrator #2
Full documentation

Load DLL

You need to load the DLL from inside MUSHclient, within a Lua scripting environment (main program or plugin):


  assert (loadlib ("G15_Display.dll", "luaopen_g15")) ()  -- install
  g15.SetAsForeground (true)  -- bring to foreground


For Lua 5.1 onwards (MUSHclient 3.80 onwards) you need to use package.loadlib, like this:


  assert (package.loadlib ("G15_Display.dll", "luaopen_g15")) ()  -- install





Once installed, the g15 table has the following functions:

IsOpen - check if the keyboard interface loaded OK.


  assert (g15.IsOpen ())


IsConnected - check if the keyboard is connected OK. If not, other functions will raise an error.

  
  assert (g15.IsConnected ())


Update - force an update of the LCD screen - done automatically after setting text but you can do it manually if you are using scrolling text, say every second or so.


  g15.Update ()


AddText - adds a new "text" object, returning a userdata which can be used to change the text in it.

All arguments have defaults.

Syntax:


  tud = g15.addtext (type, size, align, pixels, x, y)


  • type = one of: static/scrolling (default: static)
  • size = one of: small/medium/big (default: small)
  • align = one of: left/center/right (default: left)
  • pixels = maximum width in pixels (eg. up to 160) (default: 80)
  • x = X-position (0 = left) (default: 0)
  • y = Y-position (0 = top) (default: 0)


eg.

  hp_text = g15.AddText ("static", "small", "right", 40, 0, 0)


Small text is 7 point, medium is 8 point, big is 12 point.

AddProgressBar - adds a new "progress bar" object, returning a userdata which can be used to change the progress amount in it.

All arguments have defaults.

Syntax:


  pud = g15.AddProgressBar (type, sizeX, sizeY, x, y)


  • type = one of: cursor/filled/dot (default: cursor)
  • sizeX = width in pixels (default: 120)
  • sizeY = height in pixels (default: 5)
  • x = X-position (0 = left) (default: 0)
  • y = Y-position (0 = top) (default: 0)


eg.


  hp_bar  = g15.AddProgressBar ("filled", 100, 8, 50, 0) 


SetAsForeground - brings that page on the LCD screen to the front or back.


  g15.SetAsForeground (true)  -- make foreground


ButtonTriggered - returns true if the corresponding button is triggered

  
  print (g15.ButtonTriggered (2))


ButtonReleased - returns true if the corresponding button is released


  print (g15.ButtonReleased (3))


ButtonIsPressed - returns true if the corresponding button is pressed right now


  print (g15.ButtonIsPressed (4))


Close - closes the G15 library, releasing the LCD device


  g15.Close ()


The Close function was released on 16 April 2007 in the Lua 5.1 version, and is intended to be used in OnPluginClose to properly release the device.




Text Methods

Once you have created a text object with g15.AddText you can do the following things to it:

set - set the text

eg.


  hp_text:set ("Your health is low")


Note the colon after the userdata, which makes it supply the userdata itself as the first argument (the "self" parameter).

visible - make visible or invisible

eg.


  hp_text:visible (true)  -- make visible




Progress Bar Methods

Once you have created a progress bar object with g15.AddProgressBar you can do the following things to it:

percent - set the percentage filled

eg.


  hp_bar:percent (45)  -- make 45% filled


Note the colon after the userdata, which makes it supply the userdata itself as the first argument (the "self" parameter).

If the argument is outside the range 0 to 100 it is forced into that range.

visible - make visible or invisible

eg.

  hp_bar:visible (false)  -- make invisible





Notes

  • The LCD screen size currently is 160 x 43 pixels.
  • Personally I couldn't get ButtonTriggered and ButtonReleased to do anything. However ButtonIsPressed seemed to correctly return true if the button was held down when the call is made.
  • I seem to be having problems with the display disconnecting if the computer goes to sleep. Perhaps this wouldn't happen in practice, but I have released an updated DLL recently that removes the test for whether or not the display is connected. You can still test it yourself with IsConnected, but the other functions will now complete, whether or not the display is connected (I think).
  • I wasn't able to work out how to reliably remove things (other than making it crash <groan>), however I thought you probably would have a standard setup that doesn't need changing much. The SDK implements some sort of "pages" concept that I couldn't see a great use for. If you wanted to have two (or more) pages of information you can probably use the "visible" property to do this. Make two sets of things, one visible and the other invisible, and toggle back and forth between them.
Amended on Sun 15 Apr 2007 10:47 PM by Nick Gammon
Australia Forum Administrator #3
Source code

The source code is in the same file you can download:

http://www.gammon.com.au/files/mushclient/G15_Display.zip

I haven't included the Logitech SDK, you would need to obtain that from Logitech as part of the purchase of the keyboard, or subsequent upgrade.

You are welcome to adapt it to your own purposes.

Please let me know if you find problems or make significant improvements.
Amended on Fri 16 Jun 2006 06:00 AM by Nick Gammon
USA #4
Nick, this is really, really cool. Three thumbs up. Makes me want to get one of these keyboards. :-) Extra information display is something I've been thinking about for a long time. It would be nifty to have things like the time, temperature, cpu usage all "right at your fingertips", literally.
Russia #5
This must be the coolest use of a keyboard I've ever heard about! Health, mana gauges and exits on the keyboard's display... How much does that thing cost, by the way?
USA #6
Hmm, I have a Logitech MX 5000 keyboard that has a LCD screen. Any idea if this'll work on mine?
USA #7
No idea, Zeno...

Nick, that is one very cool looking keyboard, I'm going to have to start saving up for one. :)
USA #8
http://www.pricegrabber.com/search_getprod.php?masterid=11165862&search=logitech+g15

Looks like prices are around $65-$70 from respectable vendors.

Zeno: you'd probably have to download the SDK for your model, and make a few adjustments to the Lua library. Shouldn't be too hard; maybe the SDKs are even more or less the same.
Australia Forum Administrator #9
Quote:

I have a Logitech MX 5000 keyboard that has a LCD screen. Any idea if this'll work on mine?


Don't know, they probably have a slightly different interface, perhaps just a different "service number" or something.

You could try and see. :)

If you want to compile yourself grab the SDK that comes with the keyboard. All I did was take their demo program (written in C++) and replace the "main file" (with WinMain in it) with the source file supplied in the download. I changed the type from .exe to .dll and compiled. You need to grab the Lua include files as well from the Lua download (lua.h and so on).

I linked it against the supplied .lib file (lgLcd.lib) and all went well. You can probably compile under gcc but I haven't tried it.
Australia Forum Administrator #10
The other points of interest about this particular keyboard is that the keys are backlit (you can sort of see that in the photos as a blue light). This is customizable from off/low/high. This is useful if you are playing at night in the semi-dark, you can still read the letters.

There is also a mute button for the sound, and another switch which lets you put it into "game" mode, which disables the Windows key and the Properties key, which if you accidentally press can tend to throw into another application when you least want it.

Plus, just below the LCD screen some sort of "multimedia" center that lets you do play, pause, fast forward, rewind and a volume control, that I haven't done much with yet.
Australia Forum Administrator #11
Quote:

How much does that thing cost, by the way?


Well, if you live in Australia, I bought mine for $AUD 139.94.
USA #12
Is that tax and shipping and everything included? There's a seller here that's offering it for USD 68 before tax and shipping; it would turn be USD 73.60 after tax, and probably about USD 80 after shipping. According to xe.com, AUD 139.94 is USD 103.64; I guess that's inline with the general difference in electronics costs.

I was shocked when I went to the UK over Christmas that electronics cost the same numeric value as in the USA, but in pounds! So a 1GB flash card would cost about USD 65 here, but also GBP 65. But, GBP 65 = USD 120.25... so it's almost twice as much!
Australia Forum Administrator #13
That price included the 10% GST tax that our government saw fit to impose on us. I picked it up in person so shipping would have been extra.

I suppose you could expect to pay a bit more for shipping to Australia, but if it is made in China or somewhere like that, that should have been about the same as shipping it to the USA.
USA #14
Sales tax here (in California) is 8.25%. (It's different in other states, in fact, some states don't have sales tax at all...) But the catch is that it's almost never included in the price; you have to mentally juggle with prices, always adding the sales tax. It's actually pretty annoying. :/ I think it's a marketing trick: they want to make the price appear smaller, in order to encourage consumption. And it works: some people tried including the tax in the price, and people went to competitors even if the competitors' after-tax price was more expensive!! Pretty crazy how human psychology works, sometimes...

And the shipping is always calculated relative to retailer, not origin. (I.e., shipping from a NY retailer to a CA address is more expensive than from CA to CA, but CA to CA is usually fairly cheap.) I guess the costs of shipping from factory to retailer is reflected in the price, not in the shipping mark-up you pay when ordering online.
Russia #15
I was all set on buying this thing, but it looks like I'll have to wait for at least half a year until it finally arrives in the shops here. All I could find was a Logitech Multimedia keyboard for the absurd 230$ with a bunch of play/rewind buttons that I need about as badly as I need WinXP Media Center, or some other nonsense of the sorts.

And Ksilyan, you should email Arny and ask him for a law that would madnate the inclusion of the sales tax in the final price. We had the exact same situation in early 90's and I don't think there are many things that are as annoying as needing to figure out what 7% of a given number is and add the two together.
Australia Forum Administrator #16
Amazon seem to have it on sale for $USD 67.25.
#17
Hi,

Sorry to revive an old thread, but Im having some troubles getting the dll to load in.

I compiled a new DLL using Lua511.lib, as the one Nick compiled causes Mushclient 3.80 to crash (I'm guessing because it uses lua 5.0).

The problem im having though, is trying to load the dll in to a world....I'm using the following code:


if not g15 then
  assert (package.loadlib ("G15_Display.dll","luaopen_g15")) ()
  g15.SetAsForeground (true)
end -- if


However it keeps comming up with the following error:


Error number: 0
Event:        Run-time error
Description:  [string "Alias: "]:2: The specified procedure could not be found.

stack traceback:
	[C]: in function 'assert'
	[string "Alias: "]:2: in main chunk
Called by:    Immediate execution


Did I do something wrong when I compiled the DLL, or is there some other small/big fault?


Thanks
Amended on Tue 06 Mar 2007 05:29 AM by Wyd
Australia Forum Administrator #18
I'm not sure why you needed to compile it. Try downloading the one I compiled from:

http://www.gammon.com.au/files/mushclient/lua5.1_extras/
#19
Ah, thanks. I was using the original zip from the begining of the tread.

Wyd
Australia Forum Administrator #20
I have amended the original post to mention the newer version if you are using MUSHclient 3.80 onwards.
#21
Just noticed this thread, and i must say its a cool feature to use. I have it working mostly the way i want it. But i was wondering if anyone could help me setup a way to switch the exits.

for example if i receive "southwest, south, east, northwest" i would like to instead see "sw, s, e, nw" displayed on the screen so that everything fits.

I've been reading through the forums and saw some suggestions on using arrays and cases as the ideal way to take a variable string length and split up, im just not quite sure how it would be written exactly.
Australia Forum Administrator #22
In the trigger that handles the exits there is the line that actually displays them:


exits_text:set ("%0")


This is simply displaying the text from the MUD (%0). We need to manipulate that a bit.

This code should do it. First we declare a table of substitutions (you can add to this if you like, you must get the capitalization exactly right). Then we make the "set" line use a string.gsub which processes the entire line, looking for whole words, and substituting where found.



-- substitutions table

exits_subs = {
  north = "n",
  south = "s",
  east = "e",
  west = "w",
  northeast = "ne",
  northwest = "nw",
  southeast = "se",
  southwest = "sw",
  up = "u",
  down = "d",
  
 -- add more here
  
  }

exits_text:set ((string.gsub ("%0", "%a+", exits_subs)))

Amended on Sat 14 Apr 2007 09:00 PM by Nick Gammon
#23
Wow, i definitely went overboard in my thinking. Nice,clean, and simple solution. Thanks Nick!
Netherlands #24
I have recently gotten this baby and I must say it's great. So now I've started toying around with the Lua 5.1 version of the dll you've made available.

I made a new plugin, loaded the thing and off it went. Very nice. But any subsequent use of the plugin fails like this:


Immediate execution
[string "Plugin"]:6: LCD device not opened
stack traceback:
        [C]: in function 'SetAsForeground'
        [string "Plugin"]:6: in main chunk


I took a look at the source code and I presume you need to add a delete lcd call somewhere. Sadly I'm not a C programmer nor have a compiler standing around, but I assume there would be a luaclose hook (akin to the luaopen when loading a library) where you can kill the reference and make it possible to use the plugin for a second time?
#25
I only got that after i edited the plugin and tried to reinstall. Had to remove the plugin, close mushclient, and reinstall the plugin again.
Australia Forum Administrator #26
I have uploaded a new version to:

http://www.gammon.com.au/files/mushclient/lua5.1_extras/G15_Display.zip

(This is for Lua 5.1, that is MUSHclient 3.80 onwards).

The md5sum is: 9c409251cabff98b6d9f6ba6d28c52f1

This version adds a new method: Close.

This is intended to be called from a OnPluginClose function in your plugin. It simply deletes the lcd pointer, which hopefully will result in it releasing the appropriate resources. I haven't tested it. :)

eg.


function OnPluginClose ()
  g15.Close ()
end -- OnPluginClose 


Netherlands #27
I already figured out the 'restart' part of the deal. I can't keep doing that though, it's hard to have a conversation while coding that way. :)

Thanks Nick, it's really appreciated. I'll let you know how it works out... next time I restart my pc. (I tried using Unlocker to unload the DLL at one point, hoping to achieve the same effect.. but I can't run it at all anymore right now.. Oops ^_^)
Australia Forum Administrator #28
Quote:

I assume there would be a luaclose hook (akin to the luaopen when loading a library)


Actually there isn't exactly. All luaopen really does is add names to the Lua internal code space (that is, it adds functions to the g15 table).

I was toying with the idea of making some sort of object that would be garbage-collected, but I think manually closing like I suggested would be adequate in this case.
Netherlands #29
Bah. I'm sorry to disappoint you, but it doesn't seem to work. My plugin is as follows, and I've tested reloading both through 'reinstall' and manually using 'Remove' and 'Add' again in the Plugin menu.

I'm off on a bold guess here (again!) with only the source of your plugin to look at and nothing else.. and looking at the following code...


  // Have it initialize itself
  hRes = lcd->InitYourself(_T("MUSHclient"));

  if (hRes != S_OK)
    {
    // Something went wrong, when connecting to the LCD Manager software. 
    delete lcd;
    lcd = NULL;
    }

... I think lcd->InitYourself() may return a value other than S_OK to indicate a previous value had been found? Or maybe you need to call another function to release the LCD display hook?

Again, just guessing.. I'm curious now though and going to see if I can find the SDK somewhere. :)
Australia Forum Administrator #30
According to the source:


* RETURN VALUE
* The method returns the S_OK if it can connect to the LCD Manager
* library, or returns E_FAIL if it can not.


Also, the destructor, which should be called when you delete the object, calls:


m_output.Shutdown();


I presume this is the correct way to close it down. There doesn't seem to be a "close" call in the SDK.
Netherlands #31
Yeah, I found that too just now. It's really odd. Are you able to reproduce this or is it just my configuration somehow?
Australia Forum Administrator #32
Yes it seems to do it to me too. I made a few changes to at least eliminate the error message. This is the current plugin that works reasonably well:


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Tuesday, April 17, 2007, 9:38 AM -->
<!-- MuClient version 3.85 -->

<!-- Plugin "g15_keyboard_test" generated by Plugin Wizard -->

<!--
Set prompt in SMAUG like this:

prompt <%h/%Hhp %m/%Mm %v/%Vmv %x/%Xxp> 

-->

<muclient>
<plugin
   name="g15_keyboard_test"
   author="Nick Gammon"
   id="cf2fb62495f34eb887d7edaa"
   language="Lua"
   purpose="Shows using the Logitech G15 keyboard"
   date_written="2007-04-17 09:37:23"
   requires="3.80"
   version="1.0"
   >

</plugin>


<!--  Triggers  -->

<triggers>
  <trigger
   enabled="y"

match="^\&lt;(?P&lt;health&gt;\d+)\/(?P&lt;maxhealth&gt;\d+)hp (?P&lt;mana&gt;\d+)\/(?P&lt;maxmana&gt;\d+)m (?P&lt;move&gt;\d+)\/(?P&lt;maxmove&gt;\d+)mv (?P&lt;xp&gt;\d+)\/(?P&lt;xptolevel&gt;\d+)xp\&gt;"


   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>

if not g15.IsOpen () or not g15.IsConnected () then
  return
end -- if

if not hp_text then
  hp_text = g15.AddText ("static", "small", "right", 40, 0, 0)
  hp_bar  = g15.AddProgressBar ("filled", 100, 8, 50, 0) 
  mana_text = g15.AddText ("static", "small", "right", 40, 0, 10)
  mana_bar  = g15.AddProgressBar ("filled", 100, 8, 50, 10) 
  move_text = g15.AddText ("static", "small", "right", 40, 0, 20)
  move_bar  = g15.AddProgressBar ("filled", 100, 8, 50, 20) 
end -- if

hp_text:set ("hp: %&lt;health&gt;")
hp_bar:percent (%&lt;health&gt; / %&lt;maxhealth&gt; * 100)

mana_text:set ("m: %&lt;mana&gt;")
mana_bar:percent (%&lt;mana&gt; / %&lt;maxmana&gt; * 100)

move_text:set ("mv: %&lt;move&gt;")
move_bar:percent (%&lt;move&gt; / %&lt;maxmove&gt; * 100)
</send>
  </trigger>
  <trigger
   enabled="y"
   match="Exits: *"
   send_to="12"
   sequence="100"
  >
  <send>
if not g15.IsOpen () or not g15.IsConnected () then
  return
end -- if

if not exits_text then
  exits_text = g15.AddText ("static", "small", "left", 160, 0, 30)
end -- if

exits_text:set ((string.gsub ("%0", "%a+", exits_subs)))

</send>
  </trigger>
</triggers>

<!--  Script  -->


<script>
<![CDATA[
function OnPluginInstall ()
  assert (package.loadlib ("G15_Display.dll", "luaopen_g15")) ()

  if g15 and g15.IsOpen () then
    g15.SetAsForeground (true)
  end -- if opened ok

-- exits substitutions table

  exits_subs = {
    north = "n",
    south = "s",
    east = "e",
    west = "w",
    northeast = "ne",
    northwest = "nw",
    southeast = "se",
    southwest = "sw",
    up = "u",
    down = "d",
  
   -- add more here
  
    }

end -- OnPluginInstall

function OnPluginClose ()
  if g15 and g15.IsOpen () then
    g15.Close ()
  end -- initialized
end -- OnPluginClose 

]]>
</script>


</muclient>



All I can suggest is to do what I did when developing, and not use a plugin. That way the keyboard driver can stay initialized, while you test modifications to your trigger routines.

I found that restarting MUSHclient did it - this is a relatively quick operation. The plugin will just reload automatically if it is in the plugin list, so the only real time waster will be reconnecting to the MUD.
Amended on Tue 17 Apr 2007 12:11 AM by Nick Gammon
USA #33
Hmm. I would think this represents a rather serious problem. Wouldn't more than one plugin using the features of the keyboard (or trying to) cause the whole thing to get messed up? We are talking about an issue where the dll is a single entry kind of thing, I would guess. I.e., only one application at a time can "talk" to the keyboard through it. That would invariably be the case with multiple plugins. Or am I wrong?

We might need a wrapper or redesign of the offending dll to fix this. Something like an activex dll or application that can sit between the client and the existing interface, and let more than one thing at least "attempt" to talk to it/receive information from it. It wouldn't prevent comflicts, like two plugins trying to send data to it at the same time, but it would fix the issue of two plugins not being able to deal with its other features. And, a clever design could buffer data, with a delay, or even loop it, so that if plugin A wants to send a compass, but plugin B wants to display a name, then the wrapper could loop them, so that the compass will show up for X seconds, then the name, then the compass again, etc. Like a billboard.

This assumes I understand what the problem that everyone is having with this thing actually is.
Australia Forum Administrator #34
The DLL registers itself with the Logitech software (ie. name "MUSHclient") - other applications can still talk to it.

I can't see a huge amount of use for multiple plugins all talking to a tiny screen on the keyboard.

It is a nifty feature for keeping track of what you are doing, in one session.

I didn't write the Logitech API, I don't know why it isn't releasing correctly.
#35
For some reason the new plugin keeps giving me an error about performing an arithmetic on a nil value
#36
The only thing that doesn't work are my exits and the only arithmetic performed is here.


hp_text:set ("hp: %1")
hp_bar:percent ( "%1" / GetVariable ("health") * 100)

mana_text:set ("m: %2")
mana_bar:percent ( "%2" / GetVariable ("mana") * 100)
Australia Forum Administrator #37
You've modified it haven't you? Mine didn't have GetVariable ("health") in it, and that looks like the part that is failing.

I was pulling health from the wildcard. That is, the match was (in part):


(?P<health>\d+)


That puts the health amount into the named wildcard "health".

Then in the calculation I used:


hp_bar:percent (%<health> / %<maxhealth> * 100)


That is using that named wildcard. No variables were used.
#38
I modified it to pick up my score max health since my prompt doesnt have that. Didn't have any problems with that. I actually tested if it could read that variable by getting it and sending it back to the world which worked just fine. Just don't know why its getting stuck around here.
Australia Forum Administrator #39
Quote:

hp_bar:percent ( "%1" / GetVariable ("health") * 100)


First, I wouldn't quote "%1" because it is a number, not a string.

Second, I would check that GetVariable ("health") is doing what you expect. For example, put in:


print ("health = ", GetVariable ("health"))


You know that variables in plugins are different to world variables? If "health" is a world variable, and not specific to this plugin, you need:


GetPluginVariable ("", "health")


That will get the world's variable.
#40
Alright, i created the plugin again from your previous examples and updated it with the new stuff you added. Apparently i must have messed up somewhere with the code because it works just fine now.
Netherlands #41
I had noticed that shutting down MUSHclient fixed it, but since I tend to script while roleplaying at the same time it's quite an unfortunate problem.

Also.. I wondered.. if you were to write a normal application, used that EzLCD class (or whatever it is called) that is provided by the Logitech api, and simulated the creation of a keyboard, the releasing it and the recreating of the exact same registration with the Logitech software.. shouldn't it be able to determine whether it is some kind of Lua<>Logitech API conflict or whether it is really a bug in the API?

/me really needs to get a C++ compiler (and books) some day.
#42
After some tinkering and learning a bit of lua, I finally got this to work! Good news, it even works with the G-13 gamepad I bought. This is awesome, Nick you are my favorite.