2 Copyright © 2015, The AROS Development Team. All rights reserved.
14 #include <aros/debug.h>
16 #include <exec/types.h>
19 #include <proto/exec.h>
20 #include <proto/dos.h>
21 #include <proto/intuition.h>
22 #include <proto/muimaster.h>
23 #include <proto/utility.h>
24 #include <proto/graphics.h>
25 #include <proto/poseidon.h>
26 #include <proto/cybergraphics.h>
28 #include <libraries/mui.h>
29 #include <libraries/poseidon.h>
31 #include <clib/alib_protos.h>
33 #include <cybergraphx/cybergraphics.h>
34 #include <graphics/gfx.h>
39 #define OV534_REG_CTRL 0xF5
40 #define OV534_REG_DI 0xF4
41 #define OV534_REG_DO 0xF3
42 #define OV534_REG_MS_ADDRESS 0xF2
43 #define OV534_REG_MS_ID 0xF1
44 #define OV534_REG_SYS_CTRL 0xE7
45 #define OV534_OP_WRITE_3 0x37
46 #define OV534_OP_WRITE_2 0x33
47 #define OV534_OP_READ_2 0xf9
48 #define OV534_REG_GPIO_V0 0x23
49 #define OV534_REG_GPIO_C0 0x21
51 #define OV772X_SLAVE_ADDRESS_WRITE 0x42
52 #define OV772X_REG_VER 0x0B
53 #define OV772X_REG_PID 0x0A
56 #define mybug(l, x) D(if ((l>=MYBUG_LEVEL)||(l==-1)) { do { { bug x; } } while (0); } )
58 #define MUIA_Resolution (TAG_USER | 0x80420000) + 0
59 //#define MUIM_Action_HandlePsdEvents (TAG_USER | 0x80420000) + 1
60 #define MUIM_Action_HandleTmrEvents (TAG_USER | 0x80420000) + 2
63 extern char kitty640_pure
[];
64 //extern char kitty640_video[];
65 extern char kitty320_pure
[];
66 //extern char kitty320_video[];
68 unsigned char kitty
[640*480*4];
80 struct MsgPort
*ps3eye_epmsgport
;
81 // struct PsdEventHook *psdeventhandler;
83 struct MUI_InputHandlerNode psdeventihn
;
84 struct MUI_InputHandlerNode tmreventihn
;
87 struct PsdAppBinding
*pab
;
88 struct Hook releasehook
;
90 struct PsdInterface
*ps3eye_interface
;
92 struct PsdEndpoint
*ps3eye_ep1in
;
94 struct PsdPipe
*ps3eye_ep0pipe
;
95 struct PsdPipe
*ps3eye_ep1pipe
;
99 ULONG
ov534_reg_write(struct InstData
*data
, UBYTE reg
, UBYTE
*val
) {
100 mybug(-1, ("ov534_reg_write register %01x with value %01x\n", reg
, *val
));
102 psdPipeSetup(data
->ps3eye_ep0pipe
, URTF_OUT
|URTF_VENDOR
|URTF_DEVICE
, 0x01, 0x00, reg
);
104 return(psdDoPipe(data
->ps3eye_ep0pipe
, val
, 1));
107 ULONG
ov534_reg_read(struct InstData
*data
, UBYTE reg
, UBYTE
*val
) {
111 psdPipeSetup(data
->ps3eye_ep0pipe
, URTF_IN
|URTF_VENDOR
|URTF_DEVICE
, 0x01, 0x00, reg
);
112 ioerr
=psdDoPipe(data
->ps3eye_ep0pipe
, val
, 1);
114 mybug(-1, ("ov534_reg_read register %01x returns value %01x (ioerr %x)\n", reg
, *val
, ioerr
));
119 ULONG
ov534_reg_bitset(struct InstData
*data
, UBYTE reg
, UBYTE
*bitset
) {
124 ioerr
= ov534_reg_read(data
, reg
, &tmp
);
130 return(ov534_reg_write(data
, reg
, &tmp
));
133 ULONG
ov534_reg_bitclr(struct InstData
*data
, UBYTE reg
, UBYTE
*bitset
) {
138 if(ioerr
= ov534_reg_read(data
, reg
, &tmp
)) {
143 return(ov534_reg_write(data
, reg
, &tmp
));
146 void ov772x_reg_write(struct InstData
*data
, UBYTE reg
, UBYTE
*val
) {
150 ov534_reg_write(data
, OV534_REG_MS_ADDRESS
, &tmp
);
153 ov534_reg_write(data
, OV534_REG_DO
, &tmp
);
155 tmp
= OV534_OP_WRITE_3
;
156 ov534_reg_write(data
, OV534_REG_CTRL
, &tmp
);
160 UBYTE
ov772x_reg_read(struct InstData
*data
, UBYTE reg
) {
164 ov534_reg_write(data
, OV534_REG_MS_ADDRESS
, &tmp
);
166 tmp
= OV534_OP_WRITE_2
;
167 ov534_reg_write(data
, OV534_REG_CTRL
, &tmp
);
169 tmp
= OV534_OP_READ_2
;
170 ov534_reg_write(data
, OV534_REG_CTRL
, &tmp
);
172 ov534_reg_read(data
, OV534_REG_DI
, &tmp
);
177 void freedevice(struct InstData
*data
) {
179 if(data
->ps3eye_ep0pipe
) {
180 psdFreePipe(data
->ps3eye_ep0pipe
); // Allowed to be NULL
181 data
->ps3eye_ep0pipe
= NULL
;
182 mybug(-1, ("releasehook freed endpoint 0 pipe\n"));
185 if(data
->ps3eye_ep1pipe
) {
186 psdFreePipe(data
->ps3eye_ep1pipe
); // Allowed to be NULL
187 data
->ps3eye_ep1pipe
= NULL
;
188 mybug(-1, ("releasehook freed endpoint 1 pipe\n"));
192 /* CHECKME: Calls releasehook? */
193 psdReleaseAppBinding(data
->pab
); // Allowed to be NULL
196 mybug(-1, ("freedevice released PS3Eye camera binding\n"));
200 AROS_UFH3(void, releasehook
, AROS_UFHA(struct Hook
*, hook
, A0
), AROS_UFHA(APTR
, pab
, A2
), AROS_UFHA(struct InstData
*, data
, A1
)) {
203 mybug(-1,("PSD Dispatcher!\n"));
210 void allocdevice(struct InstData
*data
) {
215 Try to find FREE PS3Eye camera (DA_Binding = FALSE)
217 data
->pd
= psdFindDevice(NULL
, DA_VendorID
, 0x1415, DA_ProductID
, 0x2000, DA_Binding
, FALSE
, TAG_END
);
219 mybug(-1, ("allocdevice found PS3Eye camera\n"));
221 data
->releasehook
.h_Entry
= (APTR
) releasehook
;
223 data
->pab
= psdClaimAppBinding(ABA_Device
, data
->pd
,
224 ABA_ReleaseHook
, &data
->releasehook
,
226 ABA_ForceRelease
, FALSE
,
230 mybug(-1, ("allocdevice claimed PS3Eye camera\n"));
232 if((data
->ps3eye_interface
= psdFindInterface(data
->pd
, NULL
, IFA_InterfaceNum
, 0, TAG_END
))){
233 mybug(-1, ("allocdevice found interface 0\n"));
235 if((data
->ps3eye_ep0pipe
= psdAllocPipe(data
->pd
, data
->ps3eye_epmsgport
, NULL
))) {
236 mybug(-1, ("allocdevice allocated endpoint 0 pipe (CONTROL)\n"));
238 if((data
->ps3eye_ep1in
= psdFindEndpoint(data
->ps3eye_interface
, NULL
, EA_IsIn
, TRUE
, EA_EndpointNum
, 1, EA_TransferType
, USEAF_BULK
, TAG_END
))) {
239 mybug(-1, ("allocdevice found endpoint 1 (BULK) from interface 0\n"));
241 if((data
->ps3eye_ep1pipe
= psdAllocPipe(data
->pd
, data
->ps3eye_epmsgport
, data
->ps3eye_ep1in
))) {
242 mybug(-1, ("allocdevice allocated endpoint 1 pipe (BULK)\n"));
245 We need to call our set method in order for the led to luminate or not depending on the tick box (may have been pressed before usb connection)
246 Well, it seems to work...
248 SetAttrs(data
->self
, MUIA_Resolution
, data
->resolutionvga
, TAG_DONE
);
250 /* Turn the camera on */
252 ov534_reg_write(data
, OV534_REG_SYS_CTRL
, ®val
);
254 regval
= OV772X_SLAVE_ADDRESS_WRITE
;
255 ov534_reg_write(data
, OV534_REG_MS_ID
, ®val
);
257 /* probe the sensor */
258 mybug(-1, ("Sensor ID: %02x%02x\n", ov772x_reg_read(data
, OV772X_REG_PID
), ov772x_reg_read(data
, OV772X_REG_VER
)));
263 mybug(-1, ("allocdevice failed to allocate endpoint 1 pipe (BULK)\n"));
266 mybug(-1, ("allocdevice could not find endpoint 1 (BULK) from interface 0\n"));
270 mybug(-1, ("allocdevice failed to allocate endpoint 0 pipe (CONTROL)\n"));
275 psdReleaseAppBinding(data
->pab
);
276 mybug(-1, ("allocdevice released PS3Eye camera binding\n"));
279 mybug(-1, ("allocdevice unable to claim PS3Eye camera\n"));
284 IPTR
mNew(Class
*cl
, Object
*obj
, struct opSet
*msg
) {
285 mybug(-1, ("mNew gets called\n"));
287 if((obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
))) {
288 struct InstData
*data
= INST_DATA(cl
, obj
);
289 //mybug(-1, ("resolutionvga %d\n", data->resolutionvga));
290 data
->resolutionvga
= FALSE
;
295 /* Force a failure commenting this out */
297 if((data
->ps3eye_epmsgport
= CreateMsgPort())) {
298 // if((data->psdeventhandler = psdAddEventHandler(data->psdeventmsgport, ~0))) {
300 // data->psdeventihn.ihn_Object = obj;
301 // data->psdeventihn.ihn_Signals = 1UL<<data->psdeventmsgport->mp_SigBit;
302 // data->psdeventihn.ihn_Flags = 0;
303 // data->psdeventihn.ihn_Method = MUIM_Action_HandlePsdEvents;
305 data
->tmreventihn
.ihn_Object
= obj
;
306 data
->tmreventihn
.ihn_Millis
= 40;
307 data
->tmreventihn
.ihn_Flags
= MUIIHNF_TIMER
;
308 data
->tmreventihn
.ihn_Method
= MUIM_Action_HandleTmrEvents
;
316 CoerceMethod(cl
,obj
,OM_DISPOSE
);
322 IPTR
mDispose(Class
*cl
, Object
*obj
, struct opGet
*msg
) {
323 mybug(-1, ("mDispose gets called\n"));
325 struct InstData
*data
= INST_DATA(cl
, obj
);
326 //mybug(-1, ("resolutionvga %d\n", data->resolutionvga));
328 // if(data->psdeventhandler){
329 // psdRemEventHandler(data->psdeventhandler);
330 // data->psdeventhandler = NULL;
335 if(data
->ps3eye_epmsgport
) {
336 DeleteMsgPort(data
->ps3eye_epmsgport
);
337 data
->ps3eye_epmsgport
= NULL
;
340 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
343 IPTR
mSetup(Class
*cl
, Object
*obj
, struct MUIP_Setup
*msg
) {
344 mybug(-1, ("mSetup gets called\n"));
346 struct InstData
*data
= INST_DATA(cl
, obj
);
348 if (!DoSuperMethodA(cl
, obj
, (Msg
)msg
)) return FALSE
;
350 // DoMethod(_app(obj), MUIM_Application_AddInputHandler, (IPTR)&data->psdeventihn);
351 DoMethod(_app(obj
), MUIM_Application_AddInputHandler
, (IPTR
)&data
->tmreventihn
);
357 IPTR
mCleanup(Class
*cl
, Object
*obj
, struct MUIP_Cleanup
*msg
) {
358 mybug(-1, ("mCleanup gets called\n"));
360 struct InstData
*data
= INST_DATA(cl
, obj
);
362 DoMethod(_app(obj
), MUIM_Application_RemInputHandler
, (IPTR
)&data
->tmreventihn
);
363 // DoMethod(_app(obj), MUIM_Application_RemInputHandler, (IPTR)&data->psdeventihn);
365 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
368 IPTR
mSet(Class
*cl
, Object
*obj
, struct opSet
*msg
) {
369 mybug(-1, ("mSet gets called\n"));
371 struct InstData
*data
= INST_DATA(cl
, obj
);
373 struct TagItem
*tags
= msg
->ops_AttrList
;
378 while ((tag
= NextTagItem(&tags
)) != NULL
) {
379 switch(tag
->ti_Tag
) {
380 case MUIA_Resolution
:
381 data
->resolutionvga
= tag
->ti_Data
;
383 if(data
->ps3eye_ep1pipe
) {
384 if(data
->resolutionvga
) {
385 /* Turn red led on */
387 ov534_reg_bitset(data
, OV534_REG_GPIO_C0
, ®val
);
388 ov534_reg_bitset(data
, OV534_REG_GPIO_V0
, ®val
);
390 /* Turn red led off */
392 ov534_reg_bitset(data
, OV534_REG_GPIO_C0
, ®val
);
393 ov534_reg_bitclr(data
, OV534_REG_GPIO_V0
, ®val
);
397 SetAttrs(_win(obj
), MUIA_Window_Open
, FALSE
, MUIA_Window_Open
, TRUE
, TAG_DONE
);
403 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
406 IPTR
mGet(Class
*cl
, Object
*obj
, struct opGet
*msg
) {
407 mybug(0, ("mGet gets called\n"));
409 struct InstData
*data
= INST_DATA(cl
, obj
);
412 switch(msg
->opg_AttrID
) {
413 case MUIA_Resolution
:
414 *msg
->opg_Storage
= data
->resolutionvga
;
415 mybug(-1, ("mGet MUIA_Resolution = %d\n", data
->resolutionvga
));
419 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
426 IPTR
mAskMinMax(Class
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
) {
427 mybug(-1, ("mAskMinMax gets called\n"));
429 struct InstData
*data
= INST_DATA(cl
, obj
);
431 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
433 if(data
->resolutionvga
) {
434 msg
->MinMaxInfo
->MinWidth
+= 640;
435 msg
->MinMaxInfo
->MinHeight
+= 480;
436 msg
->MinMaxInfo
->DefWidth
+= 640;
437 msg
->MinMaxInfo
->DefHeight
+= 480;
439 msg
->MinMaxInfo
->MinWidth
+= 320;
440 msg
->MinMaxInfo
->MinHeight
+= 240;
441 msg
->MinMaxInfo
->DefWidth
+= 320;
442 msg
->MinMaxInfo
->DefHeight
+= 240;
448 IPTR
mShow(Class
*cl
, Object
*obj
, struct MUIP_Show
*msg
) {
449 mybug(-1, ("mShow gets called\n"));
451 struct InstData
*data
= INST_DATA(cl
, obj
);
454 data
->guisleep
= FALSE
;
456 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
461 IPTR
mHide(Class
*cl
, Object
*obj
, struct MUIP_Hide
*msg
) {
462 mybug(-1, ("mHide gets called\n"));
464 struct InstData
*data
= INST_DATA(cl
, obj
);
466 data
->guisleep
= TRUE
;
468 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
472 void DoEffect(UBYTE
*src
, UBYTE
*dest
, ULONG w
, ULONG h
) {
473 //CopyMemQuick(src, dest, w*h*4);
475 ULONG l
, i
, ir
, ig
, ib
, iw
;
482 destulong
= (ULONG
*)dest
;
485 ir
= ((rand() % 4)*w
)+(rand() % 4);
486 ig
= ((rand() % 2)*w
)+(rand() % 2);
487 ib
= ((rand() % 2)*w
)+(rand() % 2);
489 ir
= ((rand() % 2)*w
)+(rand() % 2);
490 ig
= ((rand() % 2)*w
)+(rand() % 2);
491 ib
= ((rand() % 2)*w
)+(rand() % 2);
505 if((ir
>=0) && (ir
<l
)) {
514 if((ig
>=0) && (ig
<l
)) {
523 if((ib
>=0) && (ib
<l
)) {
536 if( ((LONG
)(iw
) > z
) && ((LONG
)(iw
) < (z
+(h
/10))) ) {
542 destulong
[i
] = (ULONG
)(R
<<0|G
<<8|B
<<16);
547 IPTR
mDraw(Class
*cl
, Object
*obj
, struct MUIP_Draw
*msg
) {
548 mybug(0, ("mDraw gets called\n"));
550 struct InstData
*data
= INST_DATA(cl
, obj
);
555 static ULONG sec
=0, mic
=0, lastTick
=0, currTick
=0;
557 retval
= DoSuperMethodA(cl
, obj
, (Msg
)msg
);
559 if (!(msg
->flags
& (MADF_DRAWOBJECT
| MADF_DRAWUPDATE
))) return 0;
561 if(data
->ps3eye_ep1pipe
) {
562 for(y
= 0; y
< _mheight(obj
); y
++) {
564 col
= ((y
+ data
->pos
) / 8) % 2;
565 SetAPen(_rp(obj
), _pens(obj
)[col
? MPEN_SHADOW
: MPEN_SHINE
]);
566 RectFill(_rp(obj
), _mleft(obj
), _mtop(obj
) + y
, _mright(obj
), _mtop(obj
) + y
);
570 /* Add static distortion or old crt-monitor effect */
571 if(data
->resolutionvga
) {
572 DoEffect(kitty640_pure
, kitty
, 640, 480);
573 WritePixelArray(kitty
, 0, 0, 640*4, _rp(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
), RECTFMT_RGB032
);
574 // WritePixelArray(kitty640_pure, 0, 0, 640*4, _rp(obj), _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj), RECTFMT_RGB032); //+(rand() % (10))
577 DoEffect(kitty320_pure
, kitty
, 320, 240);
578 WritePixelArray(kitty
, 0, 0, 320*4, _rp(obj
), _mleft(obj
), _mtop(obj
), _mwidth(obj
), _mheight(obj
), RECTFMT_RGB032
);
583 //lastTick = currTick;
584 //CurrentTime(&sec, &mic);
585 //currTick = ((sec * 1000) + (mic / 1000));
586 //mybug(-1, ("Delta %d mS\n", currTick-lastTick));
591 /* Just use the timer event handler, no need for this one */
592 //IPTR mPsdEventHandler(Class *cl, Object *obj, Msg msg) {
593 // mybug(-1, ("mPsdEventHandler gets called\n"));
595 // struct InstData *data = INST_DATA(cl, obj);
599 // while((pen = GetMsg(data->psdeventmsgport))) {
606 IPTR
mTmrEventHandler(Class
*cl
, Object
*obj
, Msg msg
) {
607 mybug(0, ("mTmrEventHandler gets called\n"));
609 struct InstData
*data
= INST_DATA(cl
, obj
);
615 MUI_Redraw(obj
, MADF_DRAWUPDATE
);
621 #define BOOPSI_DISPATCHER(rettype,name,cl,obj,msg) \
622 AROS_UFH3(SAVEDS rettype, name,\
623 AROS_UFHA(Class *, cl, A0),\
624 AROS_UFHA(Object *, obj, A2),\
625 AROS_UFHA(Msg , msg, A1)) {AROS_USERFUNC_INIT
628 BOOPSI_DISPATCHER(IPTR
, classdispatcher
, cl
, obj
, msg
) {
629 mybug(0,("Class Dispatcher!\n"));
631 switch (msg
->MethodID
) {
634 return mNew(cl
,obj
,(APTR
)msg
);
636 return mDispose(cl
,obj
,(APTR
)msg
);
639 return mSetup(cl
,obj
,(APTR
)msg
);
641 return mCleanup(cl
,obj
,(APTR
)msg
);
644 return mSet(cl
,obj
,(APTR
)msg
);
646 return mGet(cl
,obj
,(APTR
)msg
);
649 return mAskMinMax(cl
,obj
,(APTR
)msg
);
651 return mHide(cl
,obj
,(APTR
)msg
);
653 return mShow(cl
,obj
,(APTR
)msg
);
656 return mDraw(cl
,obj
,(APTR
)msg
);
658 // case MUIM_Action_HandlePsdEvents:
659 // return mPsdEventHandler(cl,obj,(APTR)msg);
661 case MUIM_Action_HandleTmrEvents
:
662 return mTmrEventHandler(cl
,obj
,(APTR
)msg
);
665 return DoSuperMethodA(cl
,obj
,msg
);
670 BOOPSI_DISPATCHER_END
674 SetTaskPri(FindTask(NULL
), 15);
676 struct MUI_CustomClass
*mcc
;
678 if((ps
= OpenLibrary("poseidon.library", 4))) {
680 if((mcc
= MUI_CreateCustomClass(NULL
, "Area.mui", NULL
, sizeof(struct InstData
), classdispatcher
))) {
681 mybug(-1,("mui custon class at %p\n", mcc
));
683 Object
*app
, *window
, *tick1
, *custom
;
685 app
= ApplicationObject
,
686 SubWindow
, window
= WindowObject
,
687 MUIA_Window_Title
, "PS3Eye",
688 MUIA_Window_Activate
, TRUE
,
689 WindowContents
, HGroup
,
692 Child
, custom
= NewObject(mcc
->mcc_Class
, NULL
, TAG_DONE
),
697 MUIA_Group_SameWidth
, TRUE
,
698 GroupFrameT("Configuration"),
700 Child
, tick1
= MUI_MakeObject(MUIO_Checkmark
, NULL
),
701 Child
, MUI_MakeObject(MUIO_Label
,"640x480", 0),
703 Child
, (IPTR
) VSpace(0),
712 DoMethod(tick1
, MUIM_Notify
, MUIA_Selected
, TRUE
, (IPTR
)custom
, 3, MUIM_Set
, MUIA_Resolution
, TRUE
);
713 DoMethod(tick1
, MUIM_Notify
, MUIA_Selected
, FALSE
, (IPTR
)custom
, 3, MUIM_Set
, MUIA_Resolution
, FALSE
);
715 DoMethod(window
, MUIM_Notify
, MUIA_Window_CloseRequest
, TRUE
, app
, 2, MUIM_Application_ReturnID
, MUIV_Application_ReturnID_Quit
);
717 set(window
, MUIA_Window_Open
, TRUE
);
719 while((LONG
)DoMethod(app
, MUIM_Application_NewInput
, &sigs
) != (LONG
)MUIV_Application_ReturnID_Quit
) {
721 sigs
= Wait(sigs
| SIGBREAKF_CTRL_C
);
722 if(sigs
& SIGBREAKF_CTRL_C
)
727 MUI_DisposeObject(app
);
730 MUI_DeleteCustomClass(mcc
);
735 mybug(-1,("Exiting\n"));