Build Your Own Arcade Controls Forum
Main => Software Forum => Topic started by: headkaze on March 15, 2007, 10:03:15 pm
-
https://www.baker76.com/ledwiz-sdk/
-
Kewl
I will test it out and report in the next coupla days
:cheers:
-
Nice work, hk.
Loadman - let's look into using the DLL for v3 of the Mala plugin. :)
-
hk,
Thanks for this! :cheers:
I looked over the code. It will take a bit of time to convert from the com object, but I think it will be worth the effort.
-
If you don't have a window, you can just give the callback a null instead. Infact you don't really even need to call LWZ_REGISTER() in the callback unless you want hot swapping support, which I don't think is really necessary.
Procedure notify(reason: Integer; newDevice: LWZHANDLE) stdcall;
Begin
if (reason = LWZ_ADD) then
begin
LWZ_REGISTER(newDevice, nil);
end;
End;
You may need to write a bunch of wrapper functions to get the same sort of functionality as the ocx. What I've done in my plugin is have two arrays, one for state and one for intensity that I use to keep track of the LED's. That way you can use them when you need to turn a single output on or off.
-
If you don't have a window, you can just give the callback a null instead. Infact you don't really even need to call LWZ_REGISTER() in the callback unless you want hot swapping support, which I don't think is really necessary.
Procedure notify(reason: Integer; newDevice: LWZHANDLE) stdcall;
Begin
if (reason = LWZ_ADD) then
begin
LWZ_REGISTER(newDevice, nil);
end;
End;
You may need to write a bunch of wrapper functions to get the same sort of functionality as the ocx. What I've done in my plugin is have two arrays, one for state and one for intensity that I use to keep track of the LED's. That way you can use them when you need to turn a single output on or off.
hk,
Just an FYI - The Delphi code won't compile with nil passed to the LWZ_REGISTER for the window handle param.
E2010 Incompatible types: 'HWND' and 'Pointer'
-
hk,
Just an FYI - The Delphi code won't compile with nil passed to the LWZ_REGISTER for the window handle param.
E2010 Incompatible types: 'HWND' and 'Pointer'
I haven't had any problems compiling the unchanged code as a SDI app under Delphi 7 or Turbo Delphi 2006. I have not tried it as a dll yet
-
Loadman,
Since the com control accepted the PBA command as a string of comma separated values, I wrote this function to convert the string to a byte array. Just makes it a bit easier to convert from the com to the dll.
if ConvertPBAString('0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0',PBAVals) then
LWZ_PBA(deviceList.handles[nDevice],addr(PBAVals[0]));
function ConvertPBAString(const sPBA: string; out aPBAVals: array of byte): boolean;
var
nIndex: integer;
slistBuf: TStringList;
begin
//sPBA must be a comma seperated list of LEDWiz profile values.
slistBuf := TStringList.Create;
slistBuf.CommaText := sPBA;
if slistBuf.Count <> 32 then
begin
result := false;
exit;
end;
for nIndex := 0 to 31 do
aPBAVals[nIndex] := StrToInt(slistBuf[nIndex]);
slistBuf.Free;
result := true;
end;
-
Nice :cheers:
I will try that later.... :notworthy:
I'm thinking of having two builds of the Plugin DLL or OCX. Users can choose what they want
-
You may need to write a bunch of wrapper functions to get the same sort of functionality as the ocx. What I've done in my plugin is have two arrays, one for state and one for intensity that I use to keep track of the LED's. That way you can use them when you need to turn a single output on or off.
I haven't had a chance to try this yet (sorry, real world stuff came up) but I've gotta think that having the same functonality as the ocx internal to the dll(minus some of the less useful ones like random colors) should be top priority. Yes I can setup a buffer and control individual lights quite easily with code, but the fact that the ledwiz doesn't let you read the current light state means that only one app at a time can control the lights unless you can only set one at a time. For example j5 can't light a layout and then have mamehooker or one of the other hookers control the coin lights in mame because when the coin lights are set, all the other lights will get turned off.
-
hk,
I've got a question about the dll in regards to multiple devices. Randy's com control passes back a string of 1's and 0's representing which devices are detected. I have two ledwiz's (id1 and id2) so the com returns 1100000000000000. I assume if my second device was purchased with id3, then the com would return 1010000000000000.
But with the dll, all I know is how many devices are detected - deviceList.count. Can we assume that the device list always stores the devices in order? In my example above with id1 and id3, would id1 always come before id3 in the device list or is this dependent on the order that XP registered them?
I guess what I'm really asking is, with the dll, how can we identify each device?
I hope I'm making sense here, it's late. :dizzy:
-
Randy's com control passes back a string of 1's and 0's representing which devices are detected. I have two ledwiz's (id1 and id2) so the com returns 1100000000000000. I assume if my second device was purchased with id3, then the com would return 1010000000000000.
FYI.. Just to confirm what you assumed correctly
In RandyT's Document distributed with the OCX it explains this bit.
1010000000000000 = Led Wiz ID#1 And Led Wiz ID#3 detected
1110000000000000 = Led Wiz ID#1,Led Wiz ID#2 And Led Wiz ID#3 detected
I guess what I'm really asking is, with the dll, how can we identify each device?
Yeah..Good question I was going to investigate that tonight..
P.S I don't really care about the hot swap stuff for a LedWiz
-
P.S I don't really care about the hot swap stuff for a LedWiz
I agree.
-
E2010 Incompatible types: 'HWND' and 'Pointer'
Did you try a cast HWND(nil)? Actually just use a '0' instead should work fine.
I haven't had a chance to try this yet (sorry, real world stuff came up) but I've gotta think that having the same functonality as the ocx internal to the dll(minus some of the less useful ones like random colors) should be top priority. Yes I can setup a buffer and control individual lights quite easily with code, but the fact that the ledwiz doesn't let you read the current light state means that only one app at a time can control the lights unless you can only set one at a time. For example j5 can't light a layout and then have mamehooker or one of the other hookers control the coin lights in mame because when the coin lights are set, all the other lights will get turned off.
Without the source for the dll I can't change it to keep track of the states/intensities and let you read the them. At the moment we will have to assume that only one application will be using the LEDWiz at one time I'm afraid. I've e-mailed Randy and he dosn't have the source for it, and I've e-mailed MikeQ so perhaps he can help out. Randy has mentioned that he will give me the necessary info to write another dll but I don't want to do that. Randy has asked MikeQ not to make the source public, but he might be willing to let me modify it for the SDK but that will also mean MikeQ will have to be willing to give it to me also. If I get the source I can have states and intensities tracked and available to read and also fix the VB6 issues.
But with the dll, all I know is how many devices are detected - deviceList.count. Can we assume that the device list always stores the devices in order? In my example above with id1 and id3, would id1 always come before id3 in the device list or is this dependent on the order that XP registered them?
I'm not exactly sure about this, we might need to do some testing to find out if it's just deviceList.handle[id].
P.S I don't really care about the hot swap stuff for a LedWiz
Yes I don't believe hotswapping is really worth bothering about. I don't imagine people will be unplugging them while software is running.
-
Hot swapping is quite impossible actually. Can you image a panel with 32 outputs on it that would actually be small enough to remove on the fly? ;)
-
I've done some additional testing and it appears that the device list handles are the device ids. So identifying the devices should not be a problem. ;D
-
I've done some additional testing and it appears that the device list handles are the device ids. So identifying the devices should not be a problem. ;D
Kewl... Thanks for the info. I have not had time to play with this much yet
-
I've done some additional testing and it appears that the device list handles are the device ids. So identifying the devices should not be a problem. ;D
Does it work like this..
Say you have 3 LEDWiz devices, ID1, ID2 and ID5.
deviceList.handle[0] --> ID1
deviceList.handle[1] --> ID2
deviceList.handle[4] --> ID5
or
deviceList.handle[0] --> ID1
deviceList.handle[1] --> ID2
deviceList.handle[2] --> ID5
-
I've done some additional testing and it appears that the device list handles are the device ids. So identifying the devices should not be a problem. ;D
Does it work like this..
Say you have 3 LEDWiz devices, ID1, ID2 and ID5.
deviceList.handle[0] --> ID1
deviceList.handle[1] --> ID2
deviceList.handle[4] --> ID5
or
deviceList.handle[0] --> ID1
deviceList.handle[1] --> ID2
deviceList.handle[2] --> ID5
I only have two devices, but this is what happens:
With only ID1 plugged in; deviceList.handle[0] --> ID1
With only ID2 plugged in; deviceList.handle[0] --> ID2
With both plugged in; deviceList.handle[0] --> ID1 and deviceList.handle[1] --> ID2
Based on that, I would say it works like your 2nd example above.
Here's a modified version of the Delphi example. I added a UI which allows sending commands to individual devices. It also displays all the devices in the deviceList.
-
I've done some additional testing and it appears that the device list handles are the device ids. So identifying the devices should not be a problem. ;D
Does it work like this..
Say you have 3 LEDWiz devices, ID1, ID2 and ID5.
deviceList.handle[0] --> ID1
deviceList.handle[1] --> ID2
deviceList.handle[4] --> ID5
or
deviceList.handle[0] --> ID1
deviceList.handle[1] --> ID2
deviceList.handle[2] --> ID5
I only have two devices, but this is what happens:
With only ID1 plugged in; deviceList.handle[0] --> ID1
With only ID2 plugged in; deviceList.handle[0] --> ID2
With both plugged in; deviceList.handle[0] --> ID1 and deviceList.handle[1] --> ID2
Based on that, I would say it works like your 2nd example above.
Here's a modified version of the Delphi example. I added a UI which allows sending commands to individual devices. It also displays all the devices in the deviceList.
Thanks Arzoo and Headkaze. I finally got a chance to play with this today. It works great! ;D
It should be straight forward to use the Dll for the Led-Wiz plug-in instead of the OCX as the code to talk to the OCX is in a separate unit anyway. ;)
I just can't decide wether or not to have have two versions of the Plug-in :dunno
Youki made the point that the OCX may get updated (however unlikely) and I could get left behind with new enhancements.
It's technically no be deal for me have two versions for me as code for both has been handed to me on a plate. Thanks Again all concerned :D
Should it be a Set-up option for the user to choose?
What do you guys think? :dunno
-
Has the ocx been updated to support 49 levels of intensity yet? I very much doubt the ocx will be updated after that. All the basic functions required to communicate with the LEDWiz are in the dll, unless Randy decides to update the ROM and add more features but I doubt that will happen since what is done with the LEDWiz is really up to the developers who write the software to control it.
Personally I would go with the dll and forget about the ocx. If you write a wrapper for the dll that has all the functions of the ocx then if worse comes to worse you can always replace it back with the ocx routines. It's not hard writing your own code for things like setting the state or intensity of a single LED (like the ocx does I believe). If you have arrays that keep track of the LED's then this can all be custom written for the dll.
EDIT: BTW No reply from MikeQ :( Perhaps he really has left the scene now?
-
The real pain about the ocx is when it's updated. Two versions of the ocx can't live happily together, so if you download an app that uses version 3.0 ALL your apps have to use version 3.0. So if your favorite app isn't updated (like j5 was and I didn't know about it, unfortunately) you are screwed.
We definately need to put the buffers inside the dll so multiple devices can access it (in theory at least) and turn on/off individiual lights without interfering with each other.
I'm not fond of the ocx at all and I would have switched ages ago, if not for that unintentional "feature".
-
Thanks so much for this! It is just in time for my star ceiling theater project. :applaud:
-
It sounds like what needs to be done is a server app, based on MikeQ's DLL or whatever, which tracks the states of the inputs and can communicate with multiple clients. The server can be a canned executable and the clients can be a DLL (or OCX) of their own, which can be built into a user program.
I'm not sure I am up to this task myself. I might be able to find some code snippets on the web to help get part of the way there, but client/server apps are not something I have a lot of experience with.
If someone is good at doing this type of thing, and is seriously interested in helping out, I'll pony up the hardware for the effort.
On another note, Howard, if two programs use 2 different OCX versions and both of those versions exist on the machine, do both programs not continue to work? I may be mistaken, but does windows not look for the ocx in the folder of the executable before looking for it in the system folders? An OCX could also be created as a completely new OCX with identical functionality to avoid any potential conflicts. Of course, older software would still need to be re-compiled to be used with the new OCX, but nothing should break if it's not. Or am I missing something?
RandyT
-
An a new version of OCX can work with programs that are done to use an old version.
It just depends how you made the new version.
If on the new version you didn't change existing method name and parameter. (but you can add new method, and modify the code of existing one, just don't change the existing interface)
AND if when you compiled your OCX you didn't ask to generate a new ClassID , it will work.
If you register the OCX, it will take the place of the other in the registry , and all your programs will use the new one without any problem.
But if you changed the ClassID , it will be considered as a new OCX and old application will still looking for the old one.
(If i remember well , the fact to change the ClassID or not , is a compilation option in VB6)
-
It's a shame MikeQ has seemed to disappear, he is no longer answering my e-mails or PM's. I thought MikeQ wouldn't give the source for the dll because Randy didn't want him to, but this is not the case aparently. The ideal solution would be to have the LED states tracked by the dll in a static area of the dll that all applications can access through the dll. You can then just read or set the states with an exported function. Writing a server application will not only slow things down, but require a lot of hard work to write.
The thing is, there dosn't seem to be an awful lot of demand for a solution that supports multiple access to the LEDWiz hardware. I think in general people are happy to have support in their FE, or in some cases they may need a sort of global solution like Howards Mame Hooker application. This basically covers most scenarios I can think of right now.
-
It's on my list to use this. I really do have a list ;)
-
Loadman,
Since the com control accepted the PBA command as a string of comma separated values, I wrote this function to convert the string to a byte array. Just makes it a bit easier to convert from the com to the dll.
This was a great idea and I have utilised it for the Led-Wiz Plug-in to use the Dll. Your idea of using that function made sense as I could easily convert the existing code very easily so this allows me to release two versions (Ocx and DLL) ...
AnyWay........ I do have a question.
As your function Worked so well I decided to make another one for SBA as well. I have it working but I don't understand why I could not use the 'addr' command for my one?...
Not that it really matters as I got around it (as you can see) but it does puzzle me :dizzy:
Anyway below you see how I call both these functions PBA and SBA..
procedure SendCommand(Device: Integer; Command: string);
// If PBA Command (eg:PBA:48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48)
Begin
if LeftStr(command,4)='PBA:' then
begin
command := Rightstr(command,Length(command)-4);
if ConvertPBAString(command,brightness) then
LWZ_PBA(Device,addr(brightness[0])); // **THIS WORKS GREAT ****
end;
// If SBA Command (eg: SBA:255,255,255,255 )
if LeftStr(command,4)='SBA:' then
Begin
command := Rightstr(command,Length(command)-4); //take SBA element away
if ConvertSBAString(command,status) then
// LWZ_SBA(Device,addr(status[0]),2); // ***WHY DOESN'T THIS WORK*****
LWZ_SBA(Device,status[0],status[1],status[2],status[3],2);
end;
[\code]
-
AnyWay........ I do have a question.
As your function Worked so well I decided to make another one for SBA as well. I have it working but I don't understand why I could not use the 'addr' command for my one?...
Not that it really matters as I got around it (as you can see) but it does puzzle me :dizzy:
For some reason, Mike did not code the LWZ_SBA function to accept an array - rather, as you have discovered, you need to pass each of the 4 banks.
TLWZ_SBA = Procedure(device: LWZHANDLE; bank0, bank1, bank2, bank3: Cardinal; globalPulseSpeed: Cardinal) cdecl;
By the way, I also wrote a ConvertSBAString function ;D
-
AnyWay........ I do have a question.
As your function Worked so well I decided to make another one for SBA as well. I have it working but I don't understand why I could not use the 'addr' command for my one?...
Not that it really matters as I got around it (as you can see) but it does puzzle me :dizzy:
For some reason, Mike did not code the LWZ_SBA function to accept an array - rather, as you have discovered, you need to pass each of the 4 banks.
Thanks :D
.... If I knew what I was doing I would have worked out that Mike's Dll did not accept an array on that command myself :banghead: