Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / usb / shellapps / RocketTool.c
blob86da6fdb8ef9132a27c4e1a5d296404f8ecdbf01
1 /*
2 *----------------------------------------------------------------------------
3 * Rocket Launcher Tool for Poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
6 */
8 #include "debug.h"
10 #include <proto/dos.h>
11 #include <proto/exec.h>
12 #include <proto/poseidon.h>
13 #include <proto/intuition.h>
14 #include <proto/graphics.h>
15 #include <proto/diskfont.h>
16 #include <proto/lowlevel.h>
18 #include <libraries/lowlevel.h>
19 #include <devices/usb_hid.h>
21 #include "RocketTool.h"
22 #include <string.h>
24 #define ARGS_LEFT 0
25 #define ARGS_RIGHT 1
26 #define ARGS_UP 2
27 #define ARGS_DOWN 3
28 #define ARGS_FIRE 4
29 #define ARGS_TIME 5
30 #define ARGS_JOYPORT 6
31 #define ARGS_UNIT 7
32 #define ARGS_SIZEOF 8
34 const char RocketTool_prgname[] = "RocketTool";
35 static const char *template = "LEFT/S,RIGHT/S,UP/S,DOWN/S,FIRE/S,TIME/N/K,JOYPORT/N/K,UNIT/N/K";
36 const char RocketTool_version[] = "$VER: RocketTool 1.1 (12.06.09) by Chris Hodges <chrisly@platon42.de>";
37 static IPTR ArgsArray[ARGS_SIZEOF];
38 static struct RDArgs *ArgsHook = NULL;
40 struct Library *ps;
41 struct Library *LowLevelBase;
43 AROS_UFP3(void, releasehook,
44 AROS_UFPA(struct Hook *, hook, A0),
45 AROS_UFPA(APTR, pab, A2),
46 AROS_UFPA(struct NepClassRocket *, nch, A1));
48 struct NepClassRocket * SetupRocket(void);
49 struct NepClassRocket * AllocRocket(struct NepClassRocket *nch);
50 void FreeRocket(struct NepClassRocket *nch);
52 AROS_UFH3(void, releasehook,
53 AROS_UFHA(struct Hook *, hook, A0),
54 AROS_UFHA(APTR, pab, A2),
55 AROS_UFHA(struct NepClassRocket *, nch, A1))
57 AROS_USERFUNC_INIT
58 /*psdAddErrorMsg(RETURN_WARN, (STRPTR) prgname,
59 "Rocket killed!");*/
60 Signal(nch->nch_Task, SIGBREAKF_CTRL_C);
61 AROS_USERFUNC_EXIT
64 struct NepClassRocket * SetupRocket(void)
66 struct NepClassRocket *nch;
67 struct PsdDevice *pd = NULL;
68 struct PsdAppBinding *pab;
69 ULONG unit;
71 if(ArgsArray[ARGS_UNIT])
73 unit = *((ULONG *) ArgsArray[ARGS_UNIT]);
74 } else {
75 unit = 0;
81 pd = psdFindDevice(pd,
82 DA_VendorID, 0x1130,
83 DA_ProductID, 0x0202,
84 TAG_END);
85 } while(pd && (unit--));
87 if(!pd)
89 PutStr("No USB Rocket Launcher found!\n");
90 return(NULL);
92 if((nch = psdAllocVec(sizeof(struct NepClassRocket))))
94 nch->nch_Device = pd;
95 nch->nch_ReleaseHook.h_Entry = (APTR) releasehook;
97 pab = psdClaimAppBinding(ABA_Device, pd,
98 ABA_ReleaseHook, &nch->nch_ReleaseHook,
99 ABA_UserData, nch,
100 ABA_ForceRelease, TRUE,
101 TAG_END);
102 if(pab)
104 if(AllocRocket(nch))
106 return(nch);
107 } else {
108 PutStr("Couldn't allocate Rocket Laucher...\n");
110 psdReleaseAppBinding(pab);
111 } else {
112 PutStr("Couldn't claim binding!\n");
114 psdFreeVec(nch);
116 PutStr("Hohum...\n");
117 } while(TRUE);
118 return(NULL);
121 struct NepClassRocket * AllocRocket(struct NepClassRocket *nch)
123 nch->nch_Task = FindTask(NULL);
125 if((nch->nch_TaskMsgPort = CreateMsgPort()))
127 nch->nch_IF0 = psdFindInterface(nch->nch_Device, NULL,
128 IFA_InterfaceNum, 0,
129 TAG_END);
130 nch->nch_IF1 = psdFindInterface(nch->nch_Device, NULL,
131 IFA_InterfaceNum, 1,
132 TAG_END);
133 if(nch->nch_IF0 && nch->nch_IF1)
135 if((nch->nch_EP0Pipe = psdAllocPipe(nch->nch_Device, nch->nch_TaskMsgPort, NULL)))
137 return(nch);
138 } else {
139 PutStr("Couldn't allocate default pipe\n");
141 } else {
142 PutStr("Couldn't find interfaces\n");
144 DeleteMsgPort(nch->nch_TaskMsgPort);
146 return(NULL);
150 void FreeRocket(struct NepClassRocket *nch)
152 APTR pab;
154 psdGetAttrs(PGA_DEVICE, nch->nch_Device,
155 DA_Binding, &pab,
156 TAG_END);
157 psdReleaseAppBinding(pab);
158 psdFreePipe(nch->nch_EP0Pipe);
159 DeleteMsgPort(nch->nch_TaskMsgPort);
160 psdFreeVec(nch);
163 BOOL SendInit(struct NepClassRocket *nch)
165 UBYTE cmd0[8] = { 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x04, 0x00 };
166 UBYTE cmd1[8] = { 0x55, 0x53, 0x42, 0x43, 0x00, 0x40, 0x02, 0x00 };
167 LONG ioerr;
169 psdPipeSetup(nch->nch_EP0Pipe, URTF_OUT|URTF_CLASS|URTF_INTERFACE, UHR_SET_REPORT, 0x0200, 1);
170 ioerr = psdDoPipe(nch->nch_EP0Pipe, cmd0, 8);
171 if(ioerr)
173 Printf("Error sending init cmd 0: %s (%ld)\n",
174 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
175 return FALSE;
177 psdPipeSetup(nch->nch_EP0Pipe, URTF_OUT|URTF_CLASS|URTF_INTERFACE, UHR_SET_REPORT, 0x0200, 1);
178 ioerr = psdDoPipe(nch->nch_EP0Pipe, cmd1, 8);
179 if(ioerr)
181 Printf("Error sending init cmd 1: %s (%ld)\n",
182 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
183 return FALSE;
185 return TRUE;
188 BOOL SendCommand(struct NepClassRocket *nch)
190 LONG ioerr;
192 psdPipeSetup(nch->nch_EP0Pipe, URTF_OUT|URTF_CLASS|URTF_INTERFACE, UHR_SET_REPORT, 0x0200, 0);
193 ioerr = psdDoPipe(nch->nch_EP0Pipe, nch->nch_Buf, 64);
194 if(ioerr)
196 Printf("Error sending command: %s (%ld)\n",
197 psdNumToStr(NTS_IOERR, ioerr, "unknown"), ioerr);
198 return FALSE;
200 return TRUE;
203 /**************************************************************************/
205 int main(int argc, char *argv[])
207 struct NepClassRocket *nch;
208 ULONG ret = RETURN_OK;
209 ULONG joyport;
211 if(!(ArgsHook = ReadArgs(template, ArgsArray, NULL)))
213 PutStr("Wrong arguments!\n");
214 return(RETURN_FAIL);
216 ps = OpenLibrary("poseidon.library", 4);
217 if(!ps)
219 FreeArgs(ArgsHook);
220 return(RETURN_FAIL);
222 if(!(nch = SetupRocket()))
224 FreeArgs(ArgsHook);
225 CloseLibrary(ps);
226 return(RETURN_ERROR);
228 if(ArgsArray[ARGS_JOYPORT])
230 // interactive mode
231 joyport = *((ULONG *) ArgsArray[ARGS_JOYPORT]);
232 if((LowLevelBase = OpenLibrary("lowlevel.library", 1)))
234 ULONG val;
235 Printf("Interactive mode using joyport %ld. Press Ctrl-C to abort.\n", joyport);
237 // FIXME this seems to be not implemented in AROS yet
238 //SetJoyPortAttrs(joyport, SJA_Reinitialize, TRUE, TAG_END);
239 //SetJoyPortAttrs(joyport, SJA_Type, SJA_TYPE_AUTOSENSE, TAG_END);
242 if(SetSignal(0,0) & SIGBREAKF_CTRL_C)
244 break;
246 val = ReadJoyPort(joyport);
247 if(((val & JP_TYPE_MASK) == JP_TYPE_JOYSTK) || ((val & JP_TYPE_MASK) == JP_TYPE_GAMECTLR))
249 nch->nch_Buf[1] = (val & JPF_JOY_LEFT) ? 1 : 0;
250 nch->nch_Buf[2] = (val & JPF_JOY_RIGHT) ? 1 : 0;
251 nch->nch_Buf[3] = (val & JPF_JOY_UP) ? 1 : 0;
252 nch->nch_Buf[4] = (val & JPF_JOY_DOWN) ? 1 : 0;
253 nch->nch_Buf[5] = (val & JPF_BUTTON_RED) ? 1 : 0;
255 if(SendInit(nch))
257 SendCommand(nch);
258 } else {
259 ret = RETURN_WARN;
260 break;
262 Delay(10);
263 } while(TRUE);
264 //SetJoyPortAttrs(1, SJA_Reinitialize, TRUE, TAG_END);
266 CloseLibrary(LowLevelBase);
267 } else {
268 ret = RETURN_FAIL;
270 } else {
271 if(ArgsArray[ARGS_LEFT])
273 nch->nch_Buf[1] = 1;
275 if(ArgsArray[ARGS_RIGHT])
277 nch->nch_Buf[2] = 1;
279 if(ArgsArray[ARGS_UP])
281 nch->nch_Buf[3] = 1;
283 if(ArgsArray[ARGS_DOWN])
285 nch->nch_Buf[4] = 1;
287 if(ArgsArray[ARGS_FIRE])
289 nch->nch_Buf[5] = 1;
291 nch->nch_Buf[6] = 0x08;
292 nch->nch_Buf[7] = 0x08;
293 if(SendInit(nch))
295 SendCommand(nch);
296 if(ArgsArray[ARGS_TIME])
298 Delay(*((ULONG *) ArgsArray[ARGS_TIME]));
299 memset(nch->nch_Buf, 0x00, 6);
300 SendInit(nch);
301 SendCommand(nch);
303 } else {
304 ret = RETURN_WARN;
307 FreeRocket(nch);
308 FreeArgs(ArgsHook);
309 CloseLibrary(ps);
310 return(ret);