Check for SYS/GL during library init. Reason is that
[AROS.git] / rom / usb / guiapps / ps3eye / ps3eye.c
blobc9079091c2b02cafc51878ef59835734966e0678
1 /*
2 Copyright © 2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #ifdef DEBUG
10 #undef DEBUG
11 #endif
12 #define DEBUG 1
14 #include <aros/debug.h>
16 #include <proto/exec.h>
17 #include <proto/dos.h>
18 #include <proto/intuition.h>
19 #include <proto/muimaster.h>
20 #include <proto/utility.h>
21 #include <proto/graphics.h>
22 #include <proto/poseidon.h>
23 #include <proto/cybergraphics.h>
25 #include <libraries/mui.h>
26 #include <libraries/poseidon.h>
28 #include <clib/alib_protos.h>
30 #include <cybergraphx/cybergraphics.h>
31 #include <graphics/gfx.h>
33 #include <stdlib.h>
35 #define MYBUG_LEVEL 1
36 #define mybug(l, x) D(if ((l>=MYBUG_LEVEL)||(l==-1)) { do { { bug x; } } while (0); } )
38 #define MUIA_Resolution (TAG_USER | 0x80420000) + 0
39 //#define MUIM_Action_HandlePsdEvents (TAG_USER | 0x80420000) + 1
40 #define MUIM_Action_HandleTmrEvents (TAG_USER | 0x80420000) + 2
42 extern char kitty640_pure[];
43 //extern char kitty640_video[];
44 extern char kitty320_pure[];
45 //extern char kitty320_video[];
47 unsigned char kitty[640*480*4];
49 struct Library *ps;
51 struct InstData {
52 BOOL guisleep;
53 BOOL resolutionvga;
55 UWORD pos;
57 struct MsgPort *ps3eye_epmsgport;
58 // struct PsdEventHook *psdeventhandler;
60 struct MUI_InputHandlerNode psdeventihn;
61 struct MUI_InputHandlerNode tmreventihn;
63 struct PsdDevice *pd;
64 struct PsdAppBinding *pab;
65 struct Hook releasehook;
67 struct PsdInterface *ps3eye_interface;
69 struct PsdEndpoint *ps3eye_ep1in;
71 struct PsdPipe *ps3eye_ep0pipe;
72 struct PsdPipe *ps3eye_ep1pipe;
76 ULONG bridge_write(struct InstData *data, UWORD reg, UWORD *val) {
77 mybug(-1, ("bridge_write register %x with value %x\n", reg, *val));
79 psdPipeSetup(data->ps3eye_ep0pipe, URTF_OUT|URTF_VENDOR|URTF_DEVICE, 0x01, 0x00, reg);
80 return(psdDoPipe(data->ps3eye_ep0pipe, val, 1));
84 ULONG bridge_read(struct InstData *data, UWORD reg, UWORD *val) {
86 ULONG ioerr;
88 psdPipeSetup(data->ps3eye_ep0pipe, URTF_IN|URTF_VENDOR|URTF_DEVICE, 0x01, 0x00, reg);
89 ioerr =psdDoPipe(data->ps3eye_ep0pipe, val, 1);
91 mybug(-1, ("bridge_read register %x returns value %x (ioerr %x)\n", reg, *val, ioerr));
93 return(ioerr);
97 void freedevice(struct InstData *data) {
99 if(data->ps3eye_ep0pipe) {
100 psdFreePipe(data->ps3eye_ep0pipe); // Allowed to be NULL
101 data->ps3eye_ep0pipe = NULL;
102 mybug(-1, ("freedevice released endpoint 0 pipe\n"));
105 if(data->ps3eye_ep1pipe) {
106 psdFreePipe(data->ps3eye_ep1pipe); // Allowed to be NULL
107 data->ps3eye_ep1pipe = NULL;
108 mybug(-1, ("freedevice released endpoint 1 pipe\n"));
111 if(data->pab) {
112 /* CHECKME: Calls releasehook? */
113 psdReleaseAppBinding(data->pab); // Allowed to be NULL
114 data->pab = NULL;
115 data->pd = NULL;
116 mybug(-1, ("freedevice released PS3Eye camera binding\n"));
120 AROS_UFH3(void, releasehook, AROS_UFHA(struct Hook *, hook, A0), AROS_UFHA(APTR, pab, A2), AROS_UFHA(struct InstData *, data, A1)) {
121 AROS_USERFUNC_INIT
123 mybug(-1,("PSD Dispatcher!\n"));
125 freedevice(data);
127 AROS_USERFUNC_EXIT
130 void allocdevice(struct InstData *data) {
132 UWORD regval;
135 Try to find FREE PS3Eye camera (DA_Binding = FALSE)
137 data->pd = psdFindDevice(NULL, DA_VendorID, 0x1415, DA_ProductID, 0x2000, DA_Binding, FALSE, TAG_END);
138 if(data->pd) {
139 mybug(-1, ("allocdevice found PS3Eye camera\n"));
141 data->releasehook.h_Entry = (APTR) releasehook;
143 data->pab = psdClaimAppBinding(ABA_Device, data->pd,
144 ABA_ReleaseHook, &data->releasehook,
145 ABA_UserData, data,
146 ABA_ForceRelease, FALSE,
147 TAG_END);
149 if(data->pab) {
150 mybug(-1, ("allocdevice claimed PS3Eye camera\n"));
152 if((data->ps3eye_interface = psdFindInterface(data->pd, NULL, IFA_InterfaceNum, 0, TAG_END))){
153 mybug(-1, ("allocdevice found interface 0\n"));
155 if((data->ps3eye_ep0pipe = psdAllocPipe(data->pd, data->ps3eye_epmsgport, NULL))) {
156 mybug(-1, ("allocdevice allocated endpoint 0 pipe (CONTROL)\n"));
158 if((data->ps3eye_ep1in = psdFindEndpoint(data->ps3eye_interface, NULL, EA_IsIn, TRUE, EA_EndpointNum, 1, EA_TransferType, USEAF_BULK, TAG_END))) {
159 mybug(-1, ("allocdevice found endpoint 1 (BULK) from interface 0\n"));
161 if((data->ps3eye_ep1pipe = psdAllocPipe(data->pd, data->ps3eye_epmsgport, data->ps3eye_ep1in))) {
162 mybug(-1, ("allocdevice allocated endpoint 1 pipe (BULK)\n"));
164 /* Turn red led on */
165 regval = 0x80;
166 bridge_write(data, 0x21, &regval);
167 bridge_write(data, 0x23, &regval);
169 UWORD i;
170 for(i=0;i<0x100;i++) {
171 bridge_read(data, i, &regval);
174 return;
176 } else {
177 mybug(-1, ("allocdevice failed to allocate endpoint 1 pipe (BULK)\n"));
179 } else {
180 mybug(-1, ("allocdevice could not find endpoint 1 (BULK) from interface 0\n"));
183 } else {
184 mybug(-1, ("allocdevice failed to allocate endpoint 0 pipe (CONTROL)\n"));
189 psdReleaseAppBinding(data->pab);
190 mybug(-1, ("allocdevice released PS3Eye camera binding\n"));
192 } else {
193 mybug(-1, ("allocdevice unable to claim PS3Eye camera\n"));
198 IPTR mNew(Class *cl, Object *obj, struct opSet *msg) {
199 mybug(-1, ("mNew gets called\n"));
201 if((obj = (Object *) DoSuperMethodA(cl, obj, (Msg) msg))) {
202 struct InstData *data = INST_DATA(cl, obj);
203 mybug(-1, ("resolutionvga %d\n", data->resolutionvga));
204 data->resolutionvga = FALSE;
206 data->pd = NULL;
207 data->pab = NULL;
209 /* Force a failure commenting this out */
210 #if 1
211 if((data->ps3eye_epmsgport = CreateMsgPort())) {
212 // if((data->psdeventhandler = psdAddEventHandler(data->psdeventmsgport, ~0))) {
214 // data->psdeventihn.ihn_Object = obj;
215 // data->psdeventihn.ihn_Signals = 1UL<<data->psdeventmsgport->mp_SigBit;
216 // data->psdeventihn.ihn_Flags = 0;
217 // data->psdeventihn.ihn_Method = MUIM_Action_HandlePsdEvents;
219 data->tmreventihn.ihn_Object = obj;
220 data->tmreventihn.ihn_Millis = 10;
221 data->tmreventihn.ihn_Flags = MUIIHNF_TIMER;
222 data->tmreventihn.ihn_Method = MUIM_Action_HandleTmrEvents;
224 return (IPTR)obj;
225 // }
227 #endif
228 CoerceMethod(cl,obj,OM_DISPOSE);
231 return (IPTR)NULL;
234 IPTR mDispose(Class *cl, Object *obj, struct opGet *msg) {
235 mybug(-1, ("mDispose gets called\n"));
237 struct InstData *data = INST_DATA(cl, obj);
238 mybug(-1, ("resolutionvga %d\n", data->resolutionvga));
240 // if(data->psdeventhandler){
241 // psdRemEventHandler(data->psdeventhandler);
242 // data->psdeventhandler = NULL;
243 // }
245 freedevice(data);
247 if(data->ps3eye_epmsgport) {
248 DeleteMsgPort(data->ps3eye_epmsgport);
249 data->ps3eye_epmsgport = NULL;
252 return DoSuperMethodA(cl, obj, (Msg) msg);
255 IPTR mSetup(Class *cl, Object *obj, struct MUIP_Setup *msg) {
256 mybug(-1, ("mSetup gets called\n"));
258 struct InstData *data = INST_DATA(cl, obj);
260 if (!DoSuperMethodA(cl, obj, (Msg)msg)) return FALSE;
262 // DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR)&data->psdeventihn);
263 DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR)&data->tmreventihn);
265 return TRUE;
269 IPTR mCleanup(Class *cl, Object *obj, struct MUIP_Cleanup *msg) {
270 mybug(-1, ("mCleanup gets called\n"));
272 struct InstData *data = INST_DATA(cl, obj);
274 DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->tmreventihn);
275 // DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->psdeventihn);
277 return DoSuperMethodA(cl, obj, (Msg)msg);
280 IPTR mSet(Class *cl, Object *obj, struct opSet *msg) {
281 mybug(-1, ("mSet gets called\n"));
283 struct InstData *data = INST_DATA(cl, obj);
285 struct TagItem *tags = msg->ops_AttrList;
286 struct TagItem *tag;
288 while ((tag = NextTagItem(&tags)) != NULL) {
289 switch(tag->ti_Tag) {
290 case MUIA_Resolution:
291 data->resolutionvga = tag->ti_Data;
292 mybug(-1, ("mSet MUIA_Resolution = %d\n", data->resolutionvga));
293 SetAttrs(_win(obj), MUIA_Window_Open, FALSE, MUIA_Window_Open, TRUE, TAG_DONE);
294 break;
299 return DoSuperMethodA(cl, obj, (Msg)msg);
302 IPTR mGet(Class *cl, Object *obj, struct opGet *msg) {
303 mybug(0, ("mGet gets called\n"));
305 struct InstData *data = INST_DATA(cl, obj);
306 IPTR retval = TRUE;
308 switch(msg->opg_AttrID) {
309 case MUIA_Resolution:
310 *msg->opg_Storage = data->resolutionvga;
311 mybug(-1, ("mGet MUIA_Resolution = %d\n", data->resolutionvga));
312 break;
314 default:
315 retval = DoSuperMethodA(cl, obj, (Msg)msg);
316 break;
319 return retval;
322 IPTR mAskMinMax(Class *cl, Object *obj, struct MUIP_AskMinMax *msg) {
323 mybug(-1, ("mAskMinMax gets called\n"));
325 struct InstData *data = INST_DATA(cl, obj);
327 DoSuperMethodA(cl, obj, (Msg)msg);
329 if(data->resolutionvga) {
330 msg->MinMaxInfo->MinWidth += 640;
331 msg->MinMaxInfo->MinHeight += 480;
332 msg->MinMaxInfo->DefWidth += 640;
333 msg->MinMaxInfo->DefHeight += 480;
334 } else {
335 msg->MinMaxInfo->MinWidth += 320;
336 msg->MinMaxInfo->MinHeight += 240;
337 msg->MinMaxInfo->DefWidth += 320;
338 msg->MinMaxInfo->DefHeight += 240;
341 return TRUE;
344 IPTR mShow(Class *cl, Object *obj, struct MUIP_Show *msg) {
345 mybug(-1, ("mShow gets called\n"));
347 struct InstData *data = INST_DATA(cl, obj);
348 IPTR retval;
350 data->guisleep = FALSE;
352 retval = DoSuperMethodA(cl, obj, (Msg)msg);
354 return retval;
357 IPTR mHide(Class *cl, Object *obj, struct MUIP_Hide *msg) {
358 mybug(-1, ("mHide gets called\n"));
360 struct InstData *data = INST_DATA(cl, obj);
362 data->guisleep = TRUE;
364 return DoSuperMethodA(cl, obj, (Msg)msg);
368 void DoEffect(UBYTE *src, UBYTE *dest, ULONG w, ULONG h) {
369 //CopyMemQuick(src, dest, w*h*4);
371 ULONG l, i, ir, ig, ib, iw;
373 static LONG z = 0;
375 UBYTE R, G, B;
377 ULONG *destulong;
378 destulong = (ULONG *)dest;
380 if(w == 640) {
381 ir = ((rand() % 4)*w)+(rand() % 4);
382 ig = ((rand() % 2)*w)+(rand() % 2);
383 ib = ((rand() % 2)*w)+(rand() % 2);
384 } else {
385 ir = ((rand() % 2)*w)+(rand() % 2);
386 ig = ((rand() % 2)*w)+(rand() % 2);
387 ib = ((rand() % 2)*w)+(rand() % 2);
390 l = w*h;
392 z += (w/320);
393 if(z>(LONG)h) {
394 z = -(h/10);
397 for(i=0; i<l; i++) {
399 iw = (i/w);
401 if((ir>=0) && (ir<l)) {
402 R = src[(ir*4)+0];
403 } else {
404 R = 0;
406 if((iw+0) % 3) {
407 R = (R|0x1f);
410 if((ig>=0) && (ig<l)) {
411 G = src[(ig*4)+1];
412 } else {
413 G = 0;
415 if((iw+1) % 3) {
416 G = (G|0x1f);
419 if((ib>=0) && (ib<l)) {
420 B = src[(ib*4)+2];
421 } else {
422 B = 0;
424 if((iw+2) % 3) {
425 B = (B|0x1f);
428 ir++;
429 ig++;
430 ib++;
432 if( ((LONG)(iw) > z) && ((LONG)(iw) < (z+(h/10))) ) {
433 R /= 2;
434 G /= 2;
435 B /= 2;
438 destulong[i] = (ULONG)(R<<0|G<<8|B<<16);
443 IPTR mDraw(Class *cl, Object *obj, struct MUIP_Draw *msg) {
444 mybug(0, ("mDraw gets called\n"));
446 struct InstData *data = INST_DATA(cl, obj);
448 WORD y;
449 IPTR retval;
451 retval = DoSuperMethodA(cl, obj, (Msg)msg);
453 if (!(msg->flags & (MADF_DRAWOBJECT | MADF_DRAWUPDATE))) return 0;
455 if(data->ps3eye_ep0pipe) {
456 for(y= 0; y < _mheight(obj); y++) {
457 WORD col;
458 col = ((y + data->pos) / 8) % 2;
459 SetAPen(_rp(obj), _pens(obj)[col ? MPEN_SHADOW : MPEN_SHINE]);
460 RectFill(_rp(obj), _mleft(obj), _mtop(obj) + y, _mright(obj), _mtop(obj) + y);
462 data->pos++;
463 } else {
464 /* Add static distortion or old crt-monitor effect */
465 if(data->resolutionvga) {
466 DoEffect(kitty640_pure, kitty, 640, 480);
467 WritePixelArray(kitty, 0, 0, 640*4, _rp(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj), RECTFMT_RGB032);
468 // WritePixelArray(kitty640_pure, 0, 0, 640*4, _rp(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj), RECTFMT_RGB032); //+(rand() % (10))
469 } else {
471 DoEffect(kitty320_pure, kitty, 320, 240);
472 WritePixelArray(kitty, 0, 0, 320*4, _rp(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj), RECTFMT_RGB032);
475 return retval;
478 /* Just use the timer event handler, no need for this one */
479 //IPTR mPsdEventHandler(Class *cl, Object *obj, Msg msg) {
480 // mybug(-1, ("mPsdEventHandler gets called\n"));
482 // struct InstData *data = INST_DATA(cl, obj);
484 // APTR pen;
486 // while((pen = GetMsg(data->psdeventmsgport))) {
487 // ReplyMsg(pen);
488 // }
490 // return TRUE;
493 IPTR mTmrEventHandler(Class *cl, Object *obj, Msg msg) {
494 mybug(0, ("mTmrEventHandler gets called\n"));
496 struct InstData *data = INST_DATA(cl, obj);
498 if(!(data->pab)) {
499 allocdevice(data);
502 MUI_Redraw(obj, MADF_DRAWUPDATE);
504 return TRUE;
508 #define BOOPSI_DISPATCHER(rettype,name,cl,obj,msg) \
509 AROS_UFH3(SAVEDS rettype, name,\
510 AROS_UFHA(Class *, cl, A0),\
511 AROS_UFHA(Object *, obj, A2),\
512 AROS_UFHA(Msg , msg, A1)) {AROS_USERFUNC_INIT
515 BOOPSI_DISPATCHER(IPTR, classdispatcher, cl, obj, msg) {
516 mybug(0,("Class Dispatcher!\n"));
518 switch (msg->MethodID) {
520 case OM_NEW:
521 return mNew(cl,obj,(APTR)msg);
522 case OM_DISPOSE:
523 return mDispose(cl,obj,(APTR)msg);
525 case MUIM_Setup:
526 return mSetup(cl,obj,(APTR)msg);
527 case MUIM_Cleanup:
528 return mCleanup(cl,obj,(APTR)msg);
530 case OM_SET:
531 return mSet(cl,obj,(APTR)msg);
532 case OM_GET:
533 return mGet(cl,obj,(APTR)msg);
535 case MUIM_AskMinMax:
536 return mAskMinMax(cl,obj,(APTR)msg);
537 case MUIM_Hide:
538 return mHide(cl,obj,(APTR)msg);
539 case MUIM_Show:
540 return mShow(cl,obj,(APTR)msg);
542 case MUIM_Draw:
543 return mDraw(cl,obj,(APTR)msg);
545 // case MUIM_Action_HandlePsdEvents:
546 // return mPsdEventHandler(cl,obj,(APTR)msg);
548 case MUIM_Action_HandleTmrEvents:
549 return mTmrEventHandler(cl,obj,(APTR)msg);
551 default:
552 return DoSuperMethodA(cl,obj,msg);
555 return 0;
557 BOOPSI_DISPATCHER_END
559 int main(void) {
561 struct MUI_CustomClass *mcc;
563 if((ps = OpenLibrary("poseidon.library", 4))) {
565 if((mcc = MUI_CreateCustomClass(NULL, "Area.mui", NULL, sizeof(struct InstData), classdispatcher))) {
566 mybug(-1,("mui custon class at %p\n", mcc));
568 Object *app, *window, *tick1, *custom;
570 app = ApplicationObject,
571 SubWindow, window = WindowObject,
572 MUIA_Window_Title, "PS3Eye",
573 MUIA_Window_Activate, TRUE,
574 WindowContents, HGroup,
575 Child, HGroup,
576 MUIA_Weight, 100,
577 Child, custom = NewObject(mcc->mcc_Class, NULL, TAG_DONE),
578 End,
580 Child, VGroup,
581 MUIA_Weight, 1,
582 MUIA_Group_SameWidth, TRUE,
583 GroupFrameT("Configuration"),
584 Child, HGroup,
585 Child, tick1 = MUI_MakeObject(MUIO_Checkmark, NULL),
586 Child, MUI_MakeObject(MUIO_Label,"640x480", 0),
587 End,
588 Child, (IPTR) VSpace(0),
589 End,
590 End,
591 End,
592 End;
594 if(app) {
595 ULONG sigs = 0;
597 DoMethod(tick1, MUIM_Notify, MUIA_Selected, TRUE, (IPTR)custom, 3, MUIM_Set, MUIA_Resolution, TRUE);
598 DoMethod(tick1, MUIM_Notify, MUIA_Selected, FALSE, (IPTR)custom, 3, MUIM_Set, MUIA_Resolution, FALSE);
600 DoMethod(window, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
602 set(window, MUIA_Window_Open, TRUE);
604 while((LONG)DoMethod(app, MUIM_Application_NewInput, &sigs) != (LONG)MUIV_Application_ReturnID_Quit) {
605 if(sigs) {
606 sigs = Wait(sigs | SIGBREAKF_CTRL_C);
607 if(sigs & SIGBREAKF_CTRL_C)
608 break;
612 MUI_DisposeObject(app);
615 MUI_DeleteCustomClass(mcc);
617 CloseLibrary(ps);
620 mybug(-1,("Exiting\n"));
621 return 0;