revert between 56095 -> 55830 in arch
[AROS.git] / rom / usb / guiapps / ps3eye / ps3eye.c
blobfe4f4f65c3d56b97c37d6ea2799692f90c80f544
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 <exec/types.h>
17 #include <stdlib.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>
36 //#include "ov534.h"
37 //#include "ov772x.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
55 #define MYBUG_LEVEL 1
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];
70 struct Library *ps;
72 struct InstData {
73 BOOL guisleep;
74 BOOL resolutionvga;
76 UWORD pos;
78 Object *self;
80 struct MsgPort *ps3eye_epmsgport;
81 // struct PsdEventHook *psdeventhandler;
83 struct MUI_InputHandlerNode psdeventihn;
84 struct MUI_InputHandlerNode tmreventihn;
86 struct PsdDevice *pd;
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) {
109 ULONG ioerr;
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));
116 return(ioerr);
119 ULONG ov534_reg_bitset(struct InstData *data, UBYTE reg, UBYTE *bitset) {
121 UBYTE tmp;
122 ULONG ioerr;
124 ioerr = ov534_reg_read(data, reg, &tmp);
125 if(ioerr) {
126 return(ioerr);
129 tmp |= *bitset;
130 return(ov534_reg_write(data, reg, &tmp));
133 ULONG ov534_reg_bitclr(struct InstData *data, UBYTE reg, UBYTE *bitset) {
135 UBYTE tmp;
136 ULONG ioerr;
138 if(ioerr = ov534_reg_read(data, reg, &tmp)) {
139 return(ioerr);
142 tmp &= ~(*bitset);
143 return(ov534_reg_write(data, reg, &tmp));
146 void ov772x_reg_write(struct InstData *data, UBYTE reg, UBYTE *val) {
148 UBYTE tmp = reg;
150 ov534_reg_write(data, OV534_REG_MS_ADDRESS, &tmp);
152 tmp = *val;
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) {
162 UBYTE tmp = 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);
174 return(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"));
191 if(data->pab) {
192 /* CHECKME: Calls releasehook? */
193 psdReleaseAppBinding(data->pab); // Allowed to be NULL
194 data->pab = NULL;
195 data->pd = 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)) {
201 AROS_USERFUNC_INIT
203 mybug(-1,("PSD Dispatcher!\n"));
205 freedevice(data);
207 AROS_USERFUNC_EXIT
210 void allocdevice(struct InstData *data) {
212 UBYTE regval, tmp;
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);
218 if(data->pd) {
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,
225 ABA_UserData, data,
226 ABA_ForceRelease, FALSE,
227 TAG_END);
229 if(data->pab) {
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 */
251 regval = 0x3a;
252 ov534_reg_write(data, OV534_REG_SYS_CTRL, &regval);
254 regval = OV772X_SLAVE_ADDRESS_WRITE;
255 ov534_reg_write(data, OV534_REG_MS_ID, &regval);
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)));
260 return;
262 } else {
263 mybug(-1, ("allocdevice failed to allocate endpoint 1 pipe (BULK)\n"));
265 } else {
266 mybug(-1, ("allocdevice could not find endpoint 1 (BULK) from interface 0\n"));
269 } else {
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"));
278 } else {
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;
292 data->pd = NULL;
293 data->pab = NULL;
295 /* Force a failure commenting this out */
296 #if 1
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;
310 data->self = obj;
312 return (IPTR)obj;
313 // }
315 #endif
316 CoerceMethod(cl,obj,OM_DISPOSE);
319 return (IPTR)NULL;
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;
331 // }
333 freedevice(data);
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);
353 return TRUE;
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;
374 struct TagItem *tag;
376 UBYTE regval;
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 */
386 regval = 0x80;
387 ov534_reg_bitset(data, OV534_REG_GPIO_C0, &regval);
388 ov534_reg_bitset(data, OV534_REG_GPIO_V0, &regval);
389 } else {
390 /* Turn red led off */
391 regval = 0x80;
392 ov534_reg_bitset(data, OV534_REG_GPIO_C0, &regval);
393 ov534_reg_bitclr(data, OV534_REG_GPIO_V0, &regval);
397 SetAttrs(_win(obj), MUIA_Window_Open, FALSE, MUIA_Window_Open, TRUE, TAG_DONE);
398 break;
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);
410 IPTR retval = TRUE;
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));
416 break;
418 default:
419 retval = DoSuperMethodA(cl, obj, (Msg)msg);
420 break;
423 return retval;
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;
438 } else {
439 msg->MinMaxInfo->MinWidth += 320;
440 msg->MinMaxInfo->MinHeight += 240;
441 msg->MinMaxInfo->DefWidth += 320;
442 msg->MinMaxInfo->DefHeight += 240;
445 return TRUE;
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);
452 IPTR retval;
454 data->guisleep = FALSE;
456 retval = DoSuperMethodA(cl, obj, (Msg)msg);
458 return retval;
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;
477 static LONG z = 0;
479 UBYTE R, G, B;
481 ULONG *destulong;
482 destulong = (ULONG *)dest;
484 if(w == 640) {
485 ir = ((rand() % 4)*w)+(rand() % 4);
486 ig = ((rand() % 2)*w)+(rand() % 2);
487 ib = ((rand() % 2)*w)+(rand() % 2);
488 } else {
489 ir = ((rand() % 2)*w)+(rand() % 2);
490 ig = ((rand() % 2)*w)+(rand() % 2);
491 ib = ((rand() % 2)*w)+(rand() % 2);
494 l = w*h;
496 z += (w/320)*2;
497 if(z>(LONG)h) {
498 z = -(h/10);
501 for(i=0; i<l; i++) {
503 iw = (i/w);
505 if((ir>=0) && (ir<l)) {
506 R = src[(ir*4)+0];
507 } else {
508 R = 0;
510 if((iw+0) % 3) {
511 R = (R|0x1f);
514 if((ig>=0) && (ig<l)) {
515 G = src[(ig*4)+1];
516 } else {
517 G = 0;
519 if((iw+1) % 3) {
520 G = (G|0x1f);
523 if((ib>=0) && (ib<l)) {
524 B = src[(ib*4)+2];
525 } else {
526 B = 0;
528 if((iw+2) % 3) {
529 B = (B|0x1f);
532 ir++;
533 ig++;
534 ib++;
536 if( ((LONG)(iw) > z) && ((LONG)(iw) < (z+(h/10))) ) {
537 R /= 2;
538 G /= 2;
539 B /= 2;
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);
552 WORD y;
553 IPTR retval;
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++) {
563 WORD col;
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);
568 data->pos++;
569 } else {
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))
575 } else {
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));
588 return retval;
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);
597 // APTR pen;
599 // while((pen = GetMsg(data->psdeventmsgport))) {
600 // ReplyMsg(pen);
601 // }
603 // return TRUE;
606 IPTR mTmrEventHandler(Class *cl, Object *obj, Msg msg) {
607 mybug(0, ("mTmrEventHandler gets called\n"));
609 struct InstData *data = INST_DATA(cl, obj);
611 if(!(data->pab)) {
612 allocdevice(data);
615 MUI_Redraw(obj, MADF_DRAWUPDATE);
617 return TRUE;
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) {
633 case OM_NEW:
634 return mNew(cl,obj,(APTR)msg);
635 case OM_DISPOSE:
636 return mDispose(cl,obj,(APTR)msg);
638 case MUIM_Setup:
639 return mSetup(cl,obj,(APTR)msg);
640 case MUIM_Cleanup:
641 return mCleanup(cl,obj,(APTR)msg);
643 case OM_SET:
644 return mSet(cl,obj,(APTR)msg);
645 case OM_GET:
646 return mGet(cl,obj,(APTR)msg);
648 case MUIM_AskMinMax:
649 return mAskMinMax(cl,obj,(APTR)msg);
650 case MUIM_Hide:
651 return mHide(cl,obj,(APTR)msg);
652 case MUIM_Show:
653 return mShow(cl,obj,(APTR)msg);
655 case MUIM_Draw:
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);
664 default:
665 return DoSuperMethodA(cl,obj,msg);
668 return 0;
670 BOOPSI_DISPATCHER_END
672 int main(void) {
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,
690 Child, HGroup,
691 MUIA_Weight, 100,
692 Child, custom = NewObject(mcc->mcc_Class, NULL, TAG_DONE),
693 End,
695 Child, VGroup,
696 MUIA_Weight, 1,
697 MUIA_Group_SameWidth, TRUE,
698 GroupFrameT("Configuration"),
699 Child, HGroup,
700 Child, tick1 = MUI_MakeObject(MUIO_Checkmark, NULL),
701 Child, MUI_MakeObject(MUIO_Label,"640x480", 0),
702 End,
703 Child, (IPTR) VSpace(0),
704 End,
705 End,
706 End,
707 End;
709 if(app) {
710 ULONG sigs = 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) {
720 if(sigs) {
721 sigs = Wait(sigs | SIGBREAKF_CTRL_C);
722 if(sigs & SIGBREAKF_CTRL_C)
723 break;
727 MUI_DisposeObject(app);
730 MUI_DeleteCustomClass(mcc);
732 CloseLibrary(ps);
735 mybug(-1,("Exiting\n"));
736 return 0;