#define FRAMECOUNT 100 #include "skeleton.h" #include #include #include #include #include #include #include #include #include struct IntuitionBase *IntuitionBase=NULL; struct GfxBase *GfxBase=NULL; struct Window *Win=NULL; struct ReBase *ReqBase=NULL; struct RastPort *RP; struct Screen *Scrn; struct TmpRas TRas; struct AreaInfo AInfo; SHORT *AreaBuffer=NULL; PLANEPTR RastSpace=NULL; int AreaSize=200; struct Process *pr=NULL; APTR oldprocesswinptr; /* Declare and initialize your NewScreen structure: */ struct NewScreen NewScrn= { 0, 0, ScrnWidth, ScrnHeight, 2, 0, 1, ScrnFlags, /* ViewModes High-resolution, Interlaced */ CUSTOMSCREEN, /* Type Your own customized screen. */ NULL, /* Font Default font. */ "KFAST SCREEN", /* Title The screen' title. */ NULL, NULL }; /* Declare and initialize your NewWindow structure: */ struct NewWindow NewWin= { 0, 10, ScrnWidth, ScrnHeight-10, 0, 1, CLOSEWINDOW|VANILLAKEY|MOUSEBUTTONS|REFRESHWINDOW, SIMPLE_REFRESH|WINDOWCLOSE|WINDOWDRAG|WINDOWDEPTH|WINDOWSIZING| ACTIVATE|RMBTRAP|GIMMEZEROZERO|REPORTMOUSE, NULL, /* FirstGadget No gadgets connected to this window. */ NULL, /* CheckMark Use Intuition's default CheckMark. */ "KFAST", /* Title Title of the window. */ NULL, /* Screen Connected to the Workbench Screen. */ NULL, /* BitMap No Custom BitMap. */ 20, 20, ScrnWidth, ScrnHeight, CUSTOMSCREEN /* Type Connected to the Workbench Screen. */ }; obj_ptr framehead = NULL; void Help(void) { static char str[] = "\ Left mouse button draw line / Right mouse button ends line\n\ While the Left button is down you can draw freehand - SLOWLY\n\n\ SPACE/BCKSPC - scroll through ALL frames\n\ n/p - Next/Prev ENTERED frame\n\ f/l - First/Last frame (100 frames available)\n\n\ I/i - Toggle IMAGE flag for the frame / set draw mode to IMAGE\n\ S/s - Toggle SKELETON flag for the frame / set draw mode to SKELETON\n\ O/o - Toggle OUTLINE flag for the frame / set draw mode to OUTLINE\n\ x/X/y/Y - toggle deceleration/acceleration in x/y tweening\n\ 0-3 - change IMAGE line color / shifted these change IMAGE fill color\n\ F - toggle Fill mode\n\n\ TAB - Change Display Mode (All, Images, or Entered)\n\ c/C - clear the current draw mode for a frame/clear everything everywhere\n\ a - Animate - generate intermediate image frames\n\ r/w - Read/Write a file\n\n\ h - Display this page"; struct TRStructure trs; trs.Text = str; trs.Controls = 0; trs.Window = 0; trs.MiddleText = 0; trs.PositiveText = 0; trs.NegativeText = "OK"; trs.Title = "KFAST Help"; trs.KeyMask = 0xFFFF; trs.textcolor = 2; trs.detailcolor = 3; trs.blockcolor = 2; trs.versionnumber = REQVERSION; trs.Timeout = 60; trs.AbortMask=0; trs.rfu1=0; TextRequest(&trs); } char TitleInfo[127]; void Attributes(int display, int draw,int entry,int ilaw,int linec,int fillc) { char displaytext[13],drawtext[13],entrytext[4],ilawtext[5],colortext[50]; if(display==ENTRY) strcpy(displaytext,"Entered"); else if(display==IMAGE) strcpy(displaytext,"Images"); else strcpy(displaytext,"All"); colortext[0] = 0; if((draw&IMAGE)==IMAGE) { if((draw&FILL)!=0) { strcpy(drawtext,"Image w/Fill"); sprintf(colortext," LC:%d FC:%d",linec,fillc); } else { strcpy(drawtext,"Image"); sprintf(colortext," LC:%d",linec); } } else if(draw==SKELETON) strcpy(drawtext,"Skeleton"); else if(draw==XOUTLINE) strcpy(drawtext,"Outline"); else strcpy(drawtext,"???"); strcpy(entrytext," "); if((entry&IMAGE)!=0) entrytext[0] = 'I'; if((entry&SKELETON)!=0) entrytext[1] = 'S'; if((entry&XOUTLINE)!=0) entrytext[2] = 'O'; strcpy(ilawtext," "); if((ilaw&XACCEL)!=0) ilawtext[0]='X'; if((ilaw&XDECEL)!=0) ilawtext[1]='x'; if((ilaw&YACCEL)!=0) ilawtext[2]='Y'; if((ilaw&YDECEL)!=0) ilawtext[3]='y'; sprintf(TitleInfo,"DISPLAY:%s DRAWMODE:%s%s ENTERED:%s ILAW:%s", displaytext,drawtext,colortext,entrytext,ilawtext); SetWindowTitles(Win,TitleInfo,(char *)-1); } BOOL init(void) { pr = (struct Process *)FindTask(NULL); if(pr==NULL) return(FALSE); oldprocesswinptr = pr->pr_WindowPtr; IntuitionBase = (struct IntuitionBase *) OpenLibrary( "intuition.library", 0 ); if( IntuitionBase == NULL ) return(FALSE); GfxBase = (struct GfxBase *) OpenLibrary( "graphics.library", 0 ); if( GfxBase == NULL ) return(FALSE); ReqBase = (struct ReqBase *) OpenLibrary( "req.library", REQVERSION ); if( ReqBase == NULL ) return(FALSE); Scrn = OpenScreen(&NewScrn); if(Scrn==NULL) return(FALSE); NewWin.Screen = Scrn; Win = (struct Window *) OpenWindow( &NewWin ); if(Win == NULL) return(FALSE); pr->pr_WindowPtr = (APTR)Win; RP = Win->RPort; AreaSize = AreaSize + MEM_BLOCKSIZE - (AreaSize%MEM_BLOCKSIZE); AreaBuffer = (SHORT *)malloc(5*AreaSize); if(AreaBuffer==NULL) return(FALSE); RastSpace = (PLANEPTR)AllocRaster(ScrnWidth,ScrnHeight); if(RastSpace==NULL) return(FALSE); InitArea(&AInfo,AreaBuffer,AreaSize); RP->AreaInfo = &AInfo; RP->TmpRas=(struct TmpRas *)InitTmpRas(&TRas,RastSpace,RASSIZE(ScrnWidth,ScrnHeight)); BNDRYOFF( RP ); new(); return(TRUE); } void fini(void) { /* not necessary with Lattice managing the Pool - and slow too if(framehead!=NULL) { new(); free(framehead,sizeof(struct object)); } */ if(AreaBuffer!=NULL) free(AreaBuffer,5*AreaSize); if(RastSpace!=NULL) FreeRaster( RastSpace, ScrnWidth, ScrnHeight ); if(pr!=NULL) pr->pr_WindowPtr = oldprocesswinptr; if(Win!=NULL) CloseWindow( Win ); if(Scrn!=NULL) CloseScreen( Scrn ); if(IntuitionBase!=NULL) CloseLibrary( IntuitionBase ); if(GfxBase!=NULL) CloseLibrary( GfxBase ); if(ReqBase!=NULL) CloseLibrary( ReqBase ); exit(0); } void main(void) { BOOL close_me, refresh, newline, adjust, fixc; int i,drawmode,linec,fillc; struct IntuiMessage IMsg,*Msg; obj_ptr currentframe,firstframe, lastframe, temp; line_ptr lastline=NULL; if(init()!=TRUE) fini(); firstframe = makeobject(); firstframe->entry = IMAGE; lastframe = makeobject(); lastframe->entry = IMAGE; addobject(firstframe,lastframe,FRAMECOUNT); addchain(framehead,firstframe); lastframe = locateframe(lastframe); firstframe = locateframe(firstframe); currentframe = firstframe; /* We have opened the window, and everything seems to be OK. */ Help(); close_me = FALSE; refresh = FALSE; newline = TRUE; drawmode = IMAGE; adjust = FALSE; fixc = FALSE; linec = 1; fillc = 3; Attributes(dispmode,drawmode,currentframe->framedown->entry, currentframe->framedown->ilaw,linec,fillc); Attributes(dispmode,drawmode,currentframe->framedown->entry, currentframe->framedown->ilaw,linec,fillc); /* Stay in the while loop until the user has selected the Close window */ /* gadget: */ while( close_me == FALSE ) { /* Wait until we have recieved a message: */ Wait( 1 << Win->UserPort->mp_SigBit ); /* As long as we can collect messages successfully we stay in the */ /* while-loop: */ while(Msg = (struct IntuiMessage *) GetMsg(Win->UserPort)) { /* After we have successfully collected the message we can read */ /* it, and save any important values which we maybe want to check */ /* later: */ memcpy((char *)&IMsg,(char *)Msg,sizeof(struct IntuiMessage)); IMsg.MouseY -= 12; /* correct for GimmeZeroZero */ /* After we have read it we reply as fast as possible: */ /* REMEMBER! Do never try to read a message after you have replied! */ /* (Some other process has maybe changed it.) */ ReplyMsg( (struct Message *)Msg ); /* Check which IDCMP flag was sent: */ switch( IMsg.Class ) { case CLOSEWINDOW: /* The user selected the Close window gadget! */ close_me=TRUE; break; case MOUSEMOVE: if(lastline==NULL) break; i = lastline->number - 1; if(i>0) { if( (lastline->pts->p[i][1]-lastline->pts->p[i-1][1])* (IMsg.MouseX-lastline->pts->p[i-1][0])- (lastline->pts->p[i][0]-lastline->pts->p[i-1][0])* (IMsg.MouseY-lastline->pts->p[i-1][1])==0) { lastline->pts->p[i][0] = IMsg.MouseX; lastline->pts->p[i][1] = IMsg.MouseY; } else { addpoint(lastline,IMsg.MouseX,IMsg.MouseY); } } else { addpoint(lastline,IMsg.MouseX,IMsg.MouseY); } DrawObject(lastline,currentframe->framedown->offset[0], currentframe->framedown->offset[1]); break; case MOUSEBUTTONS: /* The user pressed/released a mouse button. */ /* We shall now check wich button, and if it was pressed */ /* or released: */ switch( IMsg.Code ) { case SELECTDOWN: /* Left button pressed. */ if(((currentframe->framedown->entry&IMAGE)!=0) && ((drawmode&IMAGE)!=0)) { ModifyIDCMP(Win,NewWin.IDCMPFlags|MOUSEMOVE); if(currentframe->framedown->image==NULL) { lastline = addpoint(NULL,IMsg.MouseX,IMsg.MouseY); currentframe->framedown->image = lastline; if((drawmode&FILL)!=0) lastline->fillc = fillc; lastline->linec = linec; newline = FALSE; } else if(newline==TRUE) { lastline = addpoint(NULL,IMsg.MouseX,IMsg.MouseY); appendline(currentframe->framedown->image,lastline); if((drawmode&FILL)!=0) lastline->fillc = fillc; lastline->linec = linec; newline=FALSE; } else { lastline = appendpoint(currentframe->framedown->image, IMsg.MouseX,IMsg.MouseY); } } else if(((currentframe->framedown->entry&SKELETON)!=0) && ((drawmode&SKELETON)!=0)) { lastline = addpoint(currentframe->framedown->skeleton,IMsg.MouseX,IMsg.MouseY); if(currentframe->framedown->skeleton==NULL) { lastline->linec = 2; currentframe->framedown->skeleton = lastline; } } else if(((currentframe->framedown->entry&XOUTLINE)!=0) && ((drawmode&XOUTLINE)!=0)) { lastline = addpoint(currentframe->framedown->outline,IMsg.MouseX,IMsg.MouseY); if(currentframe->framedown->outline==NULL) { lastline->linec = 3; currentframe->framedown->outline= lastline; } } break; case SELECTUP: if((drawmode&IMAGE)!=0) ModifyIDCMP(Win,NewWin.IDCMPFlags); lastline = NULL; if((drawmode&FILL)!=0) { EraseFrame(currentframe); } refresh = TRUE; break; case MENUDOWN: /* Right button pressed. */ newline = TRUE; break; } break; case VANILLAKEY: /* The user pressed/released a key! */ /* Print out the translated keycode (as dec. and hex.): */ switch(IMsg.Code) { case 'f': EraseFrame(currentframe); currentframe = firstframe; refresh = TRUE; newline = TRUE; break; case 'l': EraseFrame(currentframe); currentframe = lastframe; refresh = TRUE; newline = TRUE; break; case 'n': EraseFrame(currentframe); currentframe = findtype(currentframe->framedown->next,0,&i); if(currentframe==NULL) currentframe = firstframe; else currentframe = locateframe(currentframe); refresh = TRUE; newline = TRUE; break; case 'p': EraseFrame(currentframe); currentframe = findtypeback(currentframe->framedown->prev,0,&i); if(currentframe==NULL) currentframe = lastframe; else currentframe = locateframe(currentframe); refresh = TRUE; newline = TRUE; break; case 'I': if(currentframe!=firstframe) currentframe->framedown->entry^=IMAGE; adjust = TRUE; newline = TRUE; break; case 'i': drawmode = IMAGE; adjust = TRUE; newline = TRUE; break; case 'S': currentframe->framedown->entry^=SKELETON; adjust = TRUE; break; case 's': drawmode = SKELETON; adjust = TRUE; break; case 'O': currentframe->framedown->entry^=XOUTLINE; adjust = TRUE; newline = TRUE; break; case 'o': drawmode = XOUTLINE; adjust = TRUE; break; case 'c': EraseFrame(currentframe); if((drawmode&IMAGE)!=0) { deleteline(currentframe->framedown->image); currentframe->framedown->image = NULL; } else if((drawmode&SKELETON)!=0) { deleteline(currentframe->framedown->skeleton); currentframe->framedown->skeleton = NULL; } else if((drawmode&XOUTLINE)!=0) { deleteline(currentframe->framedown->outline); currentframe->framedown->outline = NULL; } lastline = NULL; refresh = TRUE; break; case 'C': EraseFrame(currentframe); new(); firstframe = makeobject(); firstframe->entry = IMAGE; lastframe = makeobject(); lastframe->entry = IMAGE; addobject(firstframe,lastframe,FRAMECOUNT); addchain(framehead,firstframe); lastframe = locateframe(lastframe); firstframe = locateframe(firstframe); currentframe = firstframe; adjust = TRUE; break; case ' ': EraseFrame(currentframe); if(currentframe->next!=NULL) currentframe = currentframe->next; else currentframe = firstframe; refresh = TRUE; newline = TRUE; break; case 8:/* backspace */ EraseFrame(currentframe); if(currentframe->prev!=NULL) currentframe = currentframe->prev; else currentframe = lastframe; refresh = TRUE; newline = TRUE; break; case 'a': EraseFrame(currentframe); animate(firstframe->framedown); refresh = TRUE; break; case 'x': currentframe->framedown->ilaw^=XDECEL; adjust = TRUE; break; case 'X': currentframe->framedown->ilaw^=XACCEL; adjust = TRUE; break; case 'y': currentframe->framedown->ilaw^=YDECEL; adjust = TRUE; break; case 'Y': currentframe->framedown->ilaw^=YACCEL; adjust = TRUE; break; case 'w': if(filerequest()!=FALSE) save(); break; case 'r': EraseFrame(currentframe); if(filerequest()!=FALSE) { load(); } currentframe = framehead; firstframe = framehead; lastframe = framehead; while(lastframe->next!=NULL) lastframe = lastframe->next; refresh = TRUE; newline = TRUE; break; case 'h': Help(); break; case '\t': EraseFrame(currentframe); if(dispmode==IMAGE) dispmode = ENTRY; else if(dispmode==ENTRY) dispmode = ALL; else dispmode = IMAGE; refresh=TRUE; break; case 'F': drawmode ^=FILL; fixc = TRUE; break; case '0': case '1': case '2': case '3': linec = IMsg.Code - '0'; fixc = TRUE; break; case ')': fillc = 0; fixc = TRUE; break; case '!': fillc = 1; fixc = TRUE; break; case '@': fillc = 2; fixc = TRUE; break; case '#': fillc = 3; fixc = TRUE; break; case '>': temp = currentframe; do { EraseFrame(temp); temp = temp->next; if(temp==NULL) temp = firstframe; DrawFrame(temp); } while(currentframe!=temp); break; default: break; } break; case REFRESHWINDOW: BeginRefresh(Win); DrawFrame(currentframe); EndRefresh(Win,TRUE); break; } if(fixc==TRUE) { if(((drawmode&IMAGE)!=0) && (newline==FALSE)) { lastline = currentframe->framedown->image; if(lastline!=NULL) { while(lastline->next!=NULL) lastline = lastline->next; lastline->linec = linec; if((drawmode&FILL)!=0) lastline->fillc = fillc; else lastline->fillc = 0; EraseFrame(currentframe); refresh = TRUE; } } adjust = TRUE; fixc = FALSE; } if(adjust==TRUE || refresh==TRUE) { Attributes(dispmode,drawmode,currentframe->framedown->entry, currentframe->framedown->ilaw,linec,fillc); adjust = FALSE; } if(refresh==TRUE) { DrawFrame(currentframe); refresh = FALSE; } } } fini(); }