/* * im24.c * * (c) 1990 by Robert Junghans * * image/sprite-editor for programmers * */ /* needed aztec-includes: */ #include /* some patterns to make the source shorter: */ #define PTT1 GADGHCOMP,RELVERIFY,BOOLGADGET #define PTT2 50,19,PTT1,(APTR)&bor1,NULL #define PTT3 100,12,PTT1,(APTR)&bor2,NULL #define no_msg(a) (msg=(struct IntuiMessage *)GetMsg(a->UserPort))==NULL /* library-base-pointer: */ struct GfxBase *GfxBase=NULL; struct IntuitionBase *IntuitionBase=NULL; /* some vars for intuition: */ struct Screen *scr=NULL; struct ViewPort *vp; struct Window *win1=NULL,*win2=NULL,*win3=NULL,*win4,*win5=NULL,*win6,*win7, *win8=NULL,*win9,*win10,*win11,*win12=NULL,*win13,*win14, *win15,*win16,*win17; struct RastPort *rp1,*rp2,*rp3,*rp4,*rp5,*rp6,*rp7,*rp8,*rp9,*rp10,*rp11, *rp12,*rp13,*rp14,*rp15,*rp16,*rp17; UWORD bline; struct IntuiMessage *msg; long sig; ULONG class; USHORT code,id; struct Gadget *gad; SHORT xpos,ypos; /* vars for disk operations: */ struct BitMap bmap; struct FileHandle *fh=NULL; char name[30]; /* text-array to be saved as source-code: */ char src[44][58][4]; /* counter etc.: */ int i,j,k,nr,xnr,ynr,end; char buchst; /* settings: */ int colorl=1,colorr=0,anzeigen=0,xmin=5,ymin=12,xmax=502,ymax=185,bitmaps=4, aufl=1; long breite=166,hoehe=58; /* the backup- and the user-palette: */ UWORD paletteb[]={ 0x000,0xfff,0xd00,0xf60,0xff0,0x7f7,0x0d0,0x091, 0x777,0xbbb,0x4df,0x09f,0x00c,0x80a,0xc0d,0xf0f}, paletteu[16]; /* my special mouse pointer: */ USHORT mousedata[]={ 0x0000,0x0000,0x0500,0x0600,0x0500,0x0600,0x0500,0x0700,0x0880,0x0f80, 0x1040,0x1880,0xe038,0xf058,0x0000,0xf078,0xe038,0x3040,0x1040,0x1880, 0x0880,0x0700,0x0500,0x0200,0x0500,0x0600,0x0500,0x0600,0x0000,0x0000}; USHORT (*mouseptr)[]=NULL; /* the standard-80-font: */ struct TextAttr font={ (STRPTR)"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT}; /* now the 'Kraut und Rueben'-part: */ SHORT pos1[]={-1,-1,50,-1,50,19,-1,19,-1,-1}, pos2[]={0,0,99,0,99,11,0,11,0,0}, pos3[]={0,0,122,0,122,9,0,9,0,0}; struct Border bor1={0,0,1,0,JAM1,5,pos1,NULL}, bor2={0,0,1,0,JAM1,5,pos2,NULL}, bor3={-1,-1,1,0,JAM1,5,pos3,NULL}; struct IntuiText text1={1,0,JAM1,41,0,NULL,(UBYTE *)"i",NULL}, text2={1,0,JAM1,9,11,NULL,(UBYTE *)"icon",&text1}, text3={1,0,JAM1,9,11,NULL,(UBYTE *)"info",NULL}, text4={1,0,JAM1,41,0,NULL,(UBYTE *)"f",NULL}, text5={1,0,JAM1,5,11,NULL,(UBYTE *)"flood",&text4}, text6={1,0,JAM1,41,0,NULL,(UBYTE *)"u",NULL}, text7={1,0,JAM1,9,11,NULL,(UBYTE *)"undo",&text6}, text8={1,0,JAM1,41,0,NULL,(UBYTE *)"d",NULL}, text9={1,0,JAM1,9,11,NULL,(UBYTE *)"disk",&text8}, text10={1,0,JAM1,41,0,NULL,(UBYTE *)"c",NULL}, text11={1,0,JAM1,1,11,NULL,(UBYTE *)"colors",&text10}, text12={1,0,JAM1,41,0,NULL,(UBYTE *)"p",NULL}, text13={1,0,JAM1,5,11,NULL,(UBYTE *)"prefs",&text12}, text14={1,0,JAM1,41,0,NULL,(UBYTE *)"e",NULL}, text15={1,0,JAM1,1,11,NULL,(UBYTE *)"extras",&text14}, text16={1,0,JAM1,34,2,NULL,(UBYTE *)"o.k.",NULL}, text17={1,0,JAM1,41,0,NULL,(UBYTE *)"s",NULL}, text18={1,0,JAM1,9,11,NULL,(UBYTE *)"show",&text17}, text19={1,0,JAM1,41,0,NULL,(UBYTE *)"c",NULL}, text20={1,0,JAM1,5,11,NULL,(UBYTE *)"clear",&text19}, text21={1,0,JAM1,41,0,NULL,(UBYTE *)"h",NULL}, text22={1,0,JAM1,1,11,NULL,(UBYTE *)"flip h",&text21}, text23={1,0,JAM1,41,0,NULL,(UBYTE *)"v",NULL}, text24={1,0,JAM1,1,11,NULL,(UBYTE *)"flip v",&text23}, text25={1,0,JAM1,41,0,NULL,(UBYTE *)"u",NULL}, text26={1,0,JAM1,13,11,NULL,(UBYTE *)"up1",&text25}, text27={1,0,JAM1,13,11,NULL,(UBYTE *)"up2",NULL}, text28={1,0,JAM1,13,11,NULL,(UBYTE *)"up3",NULL}, text29={1,0,JAM1,41,0,NULL,(UBYTE *)"d",NULL}, text30={1,0,JAM1,5,11,NULL,(UBYTE *)"down1",&text29}, text31={1,0,JAM1,5,11,NULL,(UBYTE *)"down2",NULL}, text32={1,0,JAM1,5,11,NULL,(UBYTE *)"down3",NULL}, text33={1,0,JAM1,41,0,NULL,(UBYTE *)"r",NULL}, text34={1,0,JAM1,1,11,NULL,(UBYTE *)"right1",&text33}, text35={1,0,JAM1,1,11,NULL,(UBYTE *)"right2",NULL}, text36={1,0,JAM1,1,11,NULL,(UBYTE *)"right3",NULL}, text37={1,0,JAM1,41,0,NULL,(UBYTE *)"l",NULL}, text38={1,0,JAM1,5,11,NULL,(UBYTE *)"left1",&text37}, text39={1,0,JAM1,5,11,NULL,(UBYTE *)"left2",NULL}, text40={1,0,JAM1,5,11,NULL,(UBYTE *)"left3",NULL}, text41={1,0,JAM1,1,0,NULL,(UBYTE *)"asm",NULL}, text42={1,0,JAM1,1,11,NULL,(UBYTE *)"sprite",&text41}, text43={1,0,JAM1,1,0,NULL,(UBYTE *)"c",NULL}, text44={1,0,JAM1,1,11,NULL,(UBYTE *)"sprite",&text43}, text45={1,0,JAM1,41,0,NULL,(UBYTE *)"a",&text41}, text46={1,0,JAM1,5,11,NULL,(UBYTE *)"image",&text45}, text47={1,0,JAM1,41,0,NULL,(UBYTE *)"c",&text43}, text48={1,0,JAM1,5,11,NULL,(UBYTE *)"image",&text47}, text49={1,0,JAM1,41,0,NULL,(UBYTE *)"p",NULL}, text50={1,0,JAM1,1,0,NULL,(UBYTE *)"pal",&text49}, text51={1,0,JAM1,9,11,NULL,(UBYTE *)"ilbm",&text50}, text52={1,0,JAM1,41,0,NULL,(UBYTE *)"l",NULL}, text53={1,0,JAM1,9,11,NULL,(UBYTE *)"ilbm",&text52}, text54={1,0,JAM1,41,0,NULL,(UBYTE *)"s",NULL}, text55={1,0,JAM1,9,11,NULL,(UBYTE *)"ilbm",&text54}, text56={1,0,JAM1,41,0,NULL,(UBYTE *)"1",NULL}, text57={1,0,JAM1,5,11,NULL,(UBYTE *)"plane",&text56}, text58={1,0,JAM1,41,0,NULL,(UBYTE *)"2",NULL}, text59={1,0,JAM1,1,11,NULL,(UBYTE *)"planes",&text58}, text60={1,0,JAM1,41,0,NULL,(UBYTE *)"3",NULL}, text61={1,0,JAM1,1,11,NULL,(UBYTE *)"planes",&text60}, text62={1,0,JAM1,41,0,NULL,(UBYTE *)"4",NULL}, text63={1,0,JAM1,1,11,NULL,(UBYTE *)"planes",&text62}, text64={1,0,JAM1,26,2,NULL,(UBYTE *)"cancel",NULL}, text65={1,0,JAM1,26,2,NULL,(UBYTE *)"(o).k.",NULL}, text66={1,0,JAM1,30,2,NULL,(UBYTE *)"hires",NULL}, text67={1,0,JAM1,26,2,NULL,(UBYTE *)"normal",NULL}, text68={1,0,JAM1,0,-8,NULL,(UBYTE *)"width :",NULL}, text69={1,0,JAM1,0,-8,NULL,(UBYTE *)"height :",NULL}, text70={1,0,JAM1,30,2,NULL,(UBYTE *)"reset",NULL}, text71={1,0,JAM1,-48,1,NULL,(UBYTE *)"red :",NULL}, text72={1,0,JAM1,-64,1,NULL,(UBYTE *)"green :",NULL}, text73={1,0,JAM1,-56,1,NULL,(UBYTE *)"blue :",NULL}; struct StringInfo string1={(UBYTE *)name,NULL,0,30,0,0,0,0,0,0,NULL,0,NULL}; struct PropInfo prop1={AUTOKNOB|FREEHORIZ,0,0,0,0,0,0,0,0,0,0}, prop2={AUTOKNOB|FREEHORIZ,0,0,0x0469,0,0,0,0,0,0,0}, prop3={AUTOKNOB|FREEHORIZ,0,0,0x1000,0,0,0,0,0,0,0}, prop4={AUTOKNOB|FREEHORIZ,0,0,0x1000,0,0,0,0,0,0,0}, prop5={AUTOKNOB|FREEHORIZ,0,0,0x1000,0,0,0,0,0,0,0}; struct Image image1,image2,image3,image4,image5; struct Gadget gad1={NULL,585,12,PTT2,&text2,0,NULL,1,NULL}, gad2={&gad1,585,34,PTT2,&text3,0,NULL,2,NULL}, gad3={&gad2,585,56,PTT2,&text5,0,NULL,3,NULL}, gad4={&gad3,585,78,PTT2,&text7,0,NULL,4,NULL}, gad5={&gad4,585,100,PTT2,&text9,0,NULL,5,NULL}, gad6={&gad5,585,122,PTT2,&text11,0,NULL,6,NULL}, gad7={&gad6,585,144,PTT2,&text13,0,NULL,7,NULL}, gad8={&gad7,585,166,PTT2,&text15,0,NULL,8,NULL}, gad9={NULL,138,135,PTT3,&text16,0,NULL,9,NULL}, gad10={NULL,16,16,PTT2,&text18,0,NULL,10,NULL}, gad11={&gad10,70,16,PTT2,&text20,0,NULL,11,NULL}, gad12={&gad11,124,16,PTT2,&text22,0,NULL,12,NULL}, gad13={&gad12,178,16,PTT2,&text24,0,NULL,13,NULL}, gad14={&gad13,16,40,PTT2,&text26,0,NULL,14,NULL}, gad15={&gad14,70,40,PTT2,&text27,0,NULL,15,NULL}, gad16={&gad15,124,40,PTT2,&text28,0,NULL,16,NULL}, gad17={&gad16,16,62,PTT2,&text30,0,NULL,17,NULL}, gad18={&gad17,70,62,PTT2,&text31,0,NULL,18,NULL}, gad19={&gad18,124,62,PTT2,&text32,0,NULL,19,NULL}, gad20={&gad19,16,84,PTT2,&text34,0,NULL,20,NULL}, gad21={&gad20,70,84,PTT2,&text35,0,NULL,21,NULL}, gad22={&gad21,124,84,PTT2,&text36,0,NULL,22,NULL}, gad23={&gad22,16,106,PTT2,&text38,0,NULL,23,NULL}, gad24={&gad23,70,106,PTT2,&text39,0,NULL,24,NULL}, gad25={&gad24,124,106,PTT2,&text40,0,NULL,25,NULL}, gad26={NULL,70,84,PTT2,&text42,0,NULL,26,NULL}, gad27={&gad26,124,84,PTT2,&text44,0,NULL,27,NULL}, gad28={&gad27,70,62,PTT2,&text46,0,NULL,28,NULL}, gad29={&gad28,124,62,PTT2,&text48,0,NULL,29,NULL}, gad30={&gad29,16,38,PTT2,&text51,0,NULL,30,NULL}, gad31={&gad30,70,38,PTT2,&text53,0,NULL,31,NULL}, gad32={&gad31,124,38,PTT2,&text55,0,NULL,32,NULL}, gad33={&gad32,16,16,PTT2,&text57,0,NULL,33,NULL}, gad34={&gad33,70,16,PTT2,&text59,0,NULL,34,NULL}, gad35={&gad34,124,16,PTT2,&text61,0,NULL,35,NULL}, gad36={&gad35,178,16,PTT2,&text63,0,NULL,36,NULL}, gad37={NULL,84,15,120,10,GADGHCOMP,RELVERIFY|STRINGCENTER, STRGADGET,(APTR)&bor3,NULL,NULL,0,(APTR)&string1,37,NULL}, gad38={&gad37,12,29,PTT3,&text16,0,NULL,38,NULL}, gad39={&gad38,120,29,PTT3,&text64,0,NULL,39,NULL}, gad40={NULL,12,27,PTT3,&text64,0,NULL,40,NULL}, gad41={&gad40,120,27,PTT3,&text65,0,NULL,41,NULL}, gad42={NULL,100,27,PTT3,&text16,0,NULL,42,NULL}, gad43={NULL,24,15,PTT3,&text66,0,NULL,43,NULL}, gad44={&gad43,132,15,PTT3,&text67,0,NULL,44,NULL}, gad45={&gad44,12,39,200,10,GADGHCOMP,RELVERIFY,PROPGADGET, (APTR)&image1,NULL,&text68,0,(APTR)&prop1,45,NULL}, gad46={&gad45,12,61,200,10,GADGHCOMP,RELVERIFY,PROPGADGET, (APTR)&image2,NULL,&text69,0,(APTR)&prop2,46,NULL}, gad47={&gad46,24,77,PTT3,&text16,0,NULL,47,NULL}, gad48={&gad47,132,77,PTT3,&text64,0,NULL,48,NULL}, gad49={NULL,15,17,PTT3,&text16,0,NULL,49,NULL}, gad50={&gad49,15,30,PTT3,&text64,0,NULL,50,NULL}, gad51={&gad50,15,43,PTT3,&text70,0,NULL,51,NULL}, gad52={&gad51,190,18,100,10,GADGHCOMP,RELVERIFY,PROPGADGET, (APTR)&image3,NULL,&text71,0,(APTR)&prop3,52,NULL}, gad53={&gad52,190,31,100,10,GADGHCOMP,RELVERIFY,PROPGADGET, (APTR)&image4,NULL,&text72,0,(APTR)&prop4,53,NULL}, gad54={&gad53,190,44,100,10,GADGHCOMP,RELVERIFY,PROPGADGET, (APTR)&image5,NULL,&text73,0,(APTR)&prop5,54,NULL}; struct NewScreen ns={ 0,0,640,200,4,0,1,HIRES,CUSTOMSCREEN,&font, (UBYTE *)"ImageEditor v2.4",NULL,NULL}; struct NewWindow nw1={ 0,11,640,189,0,1,MOUSEBUTTONS|GADGETUP|CLOSEWINDOW|VANILLAKEY, WINDOWCLOSE|SMART_REFRESH|ACTIVATE|RMBTRAP,&gad8,NULL, (UBYTE *)"draw window",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw2={ 0,129,174,71,0,1,0,SMART_REFRESH|BACKDROP,NULL,NULL, (UBYTE *)"undo picture",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw3={ 174,129,174,71,0,1,0,SMART_REFRESH|BACKDROP,NULL,NULL, (UBYTE *)"origin picture",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw4={ 137,29,376,153,0,1,GADGETUP,SMART_REFRESH|ACTIVATE,&gad9,NULL, (UBYTE *)"info window",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw5={ 0,11,166,58,0,1,0,SUPER_BITMAP|BORDERLESS|BACKDROP,NULL,NULL, NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw6={ 0,11,128+60+48,10,0,1,MOUSEBUTTONS|CLOSEWINDOW|VANILLAKEY, WINDOWDRAG|WINDOWDEPTH|WINDOWCLOSE|SMART_REFRESH|ACTIVATE|RMBTRAP, NULL,NULL,(UBYTE *)"ImageEditor v2.4",NULL,NULL,0,0,0,0,WBENCHSCREEN}, nw7={ 198,33,244,134,0,1,GADGETUP|CLOSEWINDOW|VANILLAKEY, WINDOWDRAG|WINDOWCLOSE|SMART_REFRESH|ACTIVATE,&gad25,NULL, (UBYTE *)"extras window",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw8={ 0,127,176,73,0,1,CLOSEWINDOW,WINDOWDRAG|WINDOWCLOSE|SMART_REFRESH, NULL,NULL,(UBYTE *)"show window",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw9={ 0,11,498,9,0,1,0,SMART_REFRESH|BORDERLESS|BACKDROP, NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw10={ 0,11,18,174,0,1,0,SMART_REFRESH|BORDERLESS|BACKDROP, NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw11={ 198,44,244,112,0,1,GADGETUP|CLOSEWINDOW|VANILLAKEY, WINDOWDRAG|WINDOWCLOSE|SMART_REFRESH|ACTIVATE,&gad36,NULL, (UBYTE *)"disk window",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw12={ 0,11,166,58,0,1,0,SUPER_BITMAP|BORDERLESS|BACKDROP,NULL,NULL, NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw13={ 204,76,232,47,0,1,GADGETUP,WINDOWDRAG|SMART_REFRESH|ACTIVATE, &gad39,NULL,(UBYTE *)"edit name",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw14={ 0,0,232,45,0,1,GADGETUP|VANILLAKEY,WINDOWDRAG|SMART_REFRESH|ACTIVATE, &gad41,NULL,(UBYTE *)"last request",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw15={ 170,77,300,45,0,1,GADGETUP,WINDOWDRAG|SMART_REFRESH|ACTIVATE, &gad42,NULL,(UBYTE *)"aborting",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw16={ 192,51,256,97,0,1,GADGETUP|CLOSEWINDOW|VANILLAKEY|INTUITICKS, WINDOWDRAG|WINDOWCLOSE|SMART_REFRESH|ACTIVATE,&gad48,NULL, (UBYTE *)"prefs window",NULL,NULL,0,0,0,0,CUSTOMSCREEN}, nw17={ 157,68,326,63,0,1,GADGETUP|CLOSEWINDOW|VANILLAKEY|INTUITICKS, WINDOWDRAG|WINDOWCLOSE|SMART_REFRESH|ACTIVATE,&gad54,NULL, (UBYTE *)"colors window",NULL,NULL,0,0,0,0,CUSTOMSCREEN}; main() { /* init the lib-base-pointer by opening libs: */ if((GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0L))==NULL) ende(); if((IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0L))==NULL) ende(); /* my-mouse-pointer-data in chip-mem: */ if((mouseptr=AllocMem(60L,MEMF_CHIP))==NULL) ende(); CopyMem(mousedata,mouseptr,60L); /* open the screen: */ if((scr=OpenScreen(&ns))==NULL) ende(); vp=&scr->ViewPort; /* init and set the user-palette: */ for(i=0;i<16;i++) paletteu[i]=paletteb[i]; LoadRGB4(vp,paletteu,16L); /* open the main window: */ nw1.Screen=scr; if((win1=OpenWindow(&nw1))==NULL) ende(); SetPointer(win1,mouseptr,13L,16L,-7L,-6L); rp1=win1->RPort; bline=rp1->TxBaseline; SetAPen(rp1,1L); /* border the draw-area: */ rectangle(rp1,xmin-1,ymin-1,xmax+1,ymax+1); /* draw the color-gadgets: */ for(i=0;i<16;i++) rectangle(rp1,531,11+i*11,555,20+i*11); for(i=0;i<16;i++) { SetAPen(rp1,(long)i); RectFill(rp1,532L,(long)12+i*11,554L,(long)19+i*11); } SetAPen(rp1,1L); /* show the user the act colors: */ pfeil('l',1); pfeil('r',0); /* open the undo-window: */ nw2.Screen=scr; if((win2=OpenWindow(&nw2))==NULL) ende(); rp2=win2->RPort; /* open the origin-size-window: */ nw3.Screen=scr; if((win3=OpenWindow(&nw3))==NULL) ende(); rp3=win3->RPort; /* take and execute commands: */ FOREVER { if(anzeigen) while(no_msg(win1) && no_msg(win8)) sig=Wait(1L<UserPort->mp_SigBit | 1L<UserPort->mp_SigBit); else while(no_msg(win1)) WaitPort(win1->UserPort); class=msg->Class; code=msg->Code; gad=(struct Gadget *)msg->IAddress; ReplyMsg(msg); if(anzeigen && sig==1L<UserPort->mp_SigBit) { CloseWindow(win8); win8=NULL; anzeigen=0; } else { if(class==MOUSEBUTTONS) if(code==SELECTDOWN || code==MENUDOWN) { xpos=win1->MouseX; ypos=win1->MouseY; if(xpos>=xmin && xpos<=xmax && ypos>=ymin && ypos<=ymax) paint(); else if(xpos>=531 && xpos<=555 && ypos>=11 && ypos<=185) if((ypos-11)%11!=10) { nr=(ypos-11)/11; buchst=code==SELECTDOWN?'l':'r'; new_color(buchst,nr); } } if(class==GADGETUP) { id=gad->GadgetID; switch(id) { case 1: if(!iconify()) alert(); break; case 2: info(); break; case 3: if(!flood()) alert(); break; case 4: undo(); break; case 5: if(!disk()) alert(); break; case 6: if(!colors()) alert(); break; case 7: if(!prefs()) alert(); break; case 8: if(!extras()) alert(); break; } } if(class==VANILLAKEY) switch(code) { case 'i': if(!iconify()) alert(); break; case 'f': if(!flood()) alert(); break; case 'u': undo(); break; case 'd': if(!disk()) alert(); break; case 'c': if(!colors()) alert(); break; case 'p': if(!prefs()) alert(); break; case 'e': if(!extras()) alert(); break; case 'q': if(anzeigen) { CloseWindow(win8); win8=NULL; anzeigen=0; } else class=CLOSEWINDOW; break; } if(class==CLOSEWINDOW) if(request()) ende(); } } } ende() /* this function will close all basic windows, the screen, the libs and * will also release the 60 bytes of chip-memory for my mouse pointer and * then exit the program */ { if(win8) CloseWindow(win8); if(win3) CloseWindow(win3); if(win2) CloseWindow(win2); if(win1) CloseWindow(win1); if(scr) CloseScreen(scr); if(mouseptr) FreeMem(mouseptr,60L); if(IntuitionBase) CloseLibrary(IntuitionBase); if(GfxBase) CloseLibrary(GfxBase); exit(0); } rectangle(rp,x1,y1,x2,y2) /* this function is drawing a rectangle in the wished rastport at the * wished position */ struct RastPort *rp; int x1,y1,x2,y2; { Move(rp,(long)x1,(long)y1); Draw(rp,(long)x2,(long)y1); Draw(rp,(long)x2,(long)y2); Draw(rp,(long)x1,(long)y2); Draw(rp,(long)x1,(long)y1); } pfeil(side,nr) /* this function will mark the actual left/right color with a visible * arrow; passed vars: char side is 'l' for left color or anything else * (what about 'r'?) for the right color, int nr is the color number */ char side; int nr; { long in,out; if(side=='l') { in=529; out=505; } else { in=557; out=581; } Move(rp1,out,(long)11+nr*11); Draw(rp1,in,(long)16+nr*11); Move(rp1,out,(long)11+nr*11); Draw(rp1,out,(long)21+nr*11); Draw(rp1,in,(long)16+nr*11); } new_color(side,nr) /* if the user changes a color, this function will be called with the * side (char: 'l' for left or anything else for right) and the color * number passed; one of the vars colorl/colorr will be set; this function * will delete the old arrow and draw a new one */ char side; int nr; { SetAPen(rp1,0L); pfeil(side,side=='l'?colorl:colorr); if(side=='l') colorl=nr; else colorr=nr; SetAPen(rp1,1L); pfeil(side,nr); } paint() /* this function will be called when the user pushed a mouse button in the * draw-area; the actual position is set (in the main-function) in the vars * xpos and ypos; this function will copy the actual picture in the undo- * window, then select the draw color (dependind on which mouse button was * pushed) and then draw the actual point; if now the user moves the mouse * in the draw-area, this function will always draw a line from the last * point it remember (last point drawn) to the actual position; if the user * moves the pointer out of bounds, the function will start again with only * one point (when the user starts drawing or gets out of bounds, the var * xold (which remembers the last x-position) is set to an impossible value * (1000) so the next time no line will be drawn); after every point or line * this function takes a message from the draw-window-userport to see the * new actual pointer position and to check if the user is still pressing * the mouse button */ { int xold,yold,xdiff,ydiff,xabs,yabs; update(); buchst=code==SELECTDOWN?'l':'r'; xold=1000; do { xnr=(xpos-5)/(3*aufl); ynr=(ypos-12)/3; if(xnr>=0 && xnr=0 && ynr=yabs) { if(xdiff>0) for(i=1;i<=xdiff;i++) pixel(buchst,xold+i,yold+ydiff*i/xdiff); else for(i=-1;i>=xdiff;i--) pixel(buchst,xold+i,yold+ydiff*i/xdiff); } else { if(ydiff>0) for(i=1;i<=ydiff;i++) pixel(buchst,xold+xdiff*i/ydiff,yold+i); else for(i=-1;i>=ydiff;i--) pixel(buchst,xold+xdiff*i/ydiff,yold+i); } } else pixel(buchst,xnr,ynr); xold=xnr; yold=ynr; } else xold=1000; msg=(struct IntuiMessage *)GetMsg(win1->UserPort); if(msg) { class=msg->Class; code=msg->Code; ReplyMsg(msg); } xpos=win1->MouseX; ypos=win1->MouseY; } while(!(class==MOUSEBUTTONS && code==SELECTUP || code==MENUUP)); } pixel(buchst,x,y) /* this function is used to draw; it sets the draw-colors in the needed * rastports and then draw a rectangle in the draw-window, one or two points * in the origin-size-window and maybe also one or two points in the show- * window (two points are drawn when we are drawing in the lores-mode; the * mode can be set in the pref(erence)s-part) */ char buchst; int x,y; { long col; col=buchst=='l'?colorl:colorr; SetAPen(rp1,col); RectFill(rp1,(long)5+x*3*aufl,(long)12+y*3, (long)4+3*aufl+x*3*aufl,(long)14+y*3); SetAPen(rp3,col); WritePixel(rp3,(long)4+x*aufl,(long)11+y); if(aufl==2) WritePixel(rp3,(long)5+x*aufl,(long)11+y); if(anzeigen) { SetAPen(rp8,col); WritePixel(rp8,(long)5+x*aufl,(long)12+y); if(aufl==2) WritePixel(rp8,(long)6+x*aufl,(long)12+y); } } text(rp,x,y,str) /* this function is writing the wished text in the wished rastport at the * wished position; * remark: the var bline is initialized in the main-function after opening * the draw-window and it contains the number of lines the text * would be drawn higher than wished */ struct RastPort *rp; int x,y; char *str; { Move(rp,(long)x,(long)y+bline); Text(rp,str,(long)strlen(str)); } update() /* this function destroys the undo-picture by overwriting this with the * origin-picture; it is called e.g. when the user draws the next point */ { ClipBlit(rp3,4L,11L,rp2,4L,11L,breite*aufl,hoehe,(long)0xc0); } undo() /* this function will undo the last user-action by bringing the last * 'saved' picture on the draw-window */ { reverse(win1,4); ClipBlit(rp2,4L,11L,rp3,4L,11L,breite*aufl,hoehe,(long)0xc0); if(anzeigen) ClipBlit(rp3,4L,11L,rp8,5L,12L,breite*aufl,hoehe,(long)0xc0); erase(); get_msgs(); reverse(win1,4); } erase() /* because the undo-window is smaller than the draw-window (to save chip- * memory) after every undo (or after iconifying, when the picture is also * remembered in small-size) we must erase the picture, what this function * is doing (first of all the small-picture is copied in the draw-area in * the upper left corner and than this function is called) */ { for(i=breite*aufl-1;i>=0;i--) { ClipBlit(rp3,(long)4+i,11L,rp1,(long)5+i*3,12L, 1L,hoehe,(long)0xc0); ClipBlit(rp1,(long)5+i*3,12L,rp1,(long)6+i*3,12L, 1L,hoehe,(long)0xc0); ClipBlit(rp1,(long)5+i*3,12L,rp1,(long)7+i*3,12L, 1L,hoehe,(long)0xc0); } for(i=hoehe-1;i>=0;i--) { ClipBlit(rp1,5L,(long)12+i,rp1,5L,(long)12+i*3, breite*3*aufl,1L,(long)0xc0); ClipBlit(rp1,5L,(long)12+i*3,rp1,5L,(long)13+i*3, breite*3*aufl,1L,(long)0xc0); ClipBlit(rp1,5L,(long)12+i*3,rp1,5L,(long)14+i*3, breite*3*aufl,1L,(long)0xc0); } } info() /* this function is opening a window and displaying some informations to * this program */ { reverse(win1,2); nw4.Screen=scr; if((win4=OpenWindow(&nw4))==NULL) alert(); else { SetPointer(win4,mouseptr,13L,16L,-7L,-6L); rp4=win4->RPort; SetAPen(rp4,2L); text(rp4,124,15,"ImageEditor v2.4"); SetAPen(rp4,1L); text(rp4,88,27,"© 1990 by Robert Junghans"); text(rp4,84,39,"date of release: 20.Apr.90"); SetAPen(rp4,2L); text(rp4,12,51,"Tool"); SetAPen(rp4,1L); text(rp4,52,51,"for programmers interested in graphics."); text(rp4,84,59,"This program is"); SetAPen(rp4,2L); text(rp4,212,59,"Shareware."); SetAPen(rp4,1L); text(rp4,52,67,"If you use it please send $5.00 to"); text(rp4,128,75,"Robert Junghans"); text(rp4,112,83,"Agnes Straub Weg 10"); text(rp4,132,91,"1000 Berlin 47"); text(rp4,140,99,"West Germany"); text(rp4,60,111,"Improvement suggestions welcome."); text(rp4,64,123,"[ see"); SetAPen(rp4,2L); text(rp4,112,123,"im24.doc"); SetAPen(rp4,1L); text(rp4,184,123,"for more infos ]"); WaitPort(win4->UserPort); CloseWindow(win4); get_msgs(); } reverse(win1,2); } get_msgs() /* if a time-intensive function was called (e.g. undo or disk etc.) so the * user could activate some draw-window-gadgets in the time the function * was executed; to not let him wait until all 'clicked' functions will be * also executed, this function is called and it is 'clearing' the user- * ports of the draw-window and maybe of the show-window of all messages */ { message(win1); if(anzeigen) message(win8); } message(win) /* this function will 'take' all messages send to the wished window and * reply them */ struct Window *win; { while(msg=(struct IntuiMessage *)GetMsg(win->UserPort)) ReplyMsg(msg); } alert() /* this simple function displays an alert looking a little bit like * the well known meditation from india; the best way to continue is * to push the left mouse button; this function will be called when an * other function can't get the memory it needs and must be aborted */ { static BYTE alert[]={ 0,248,15,"Not enough memory!",1, 0,176,28,"The actual function will be aborted!",1, 0,128,41,"Please press the left mouse button to continue..",0}; DisplayAlert(RECOVERY_ALERT,alert,53L); } reverse(win,id) /* this function will search in the wished window-gadget-list for the * gadget with the wished id and then reverse it; if a gadget with the * given id does not exist in the list of the wished window, no gadget * will be inverted */ struct Window *win; int id; { struct RastPort *rp; struct Gadget *gad; int done; rp=win->RPort; gad=win->FirstGadget; done=0; if(gad) do { if(gad->GadgetID==id) { SetDrMd(rp,JAM1|COMPLEMENT); RectFill(rp,(long)gad->LeftEdge,(long)gad->TopEdge, (long)gad->LeftEdge+gad->Width-1, (long)gad->TopEdge+gad->Height-1); SetDrMd(rp,JAM1); done=1; } gad=gad->NextGadget; } while(gad && !done); } iconify() /* if the user needs the chip-memory which is used by im24 he must not quit * the program; he can also iconify it, i.e. the windows and the screen from * im24 will be closed and im24 will open a small window on the workbench * screen and the user can run another programs which need chip-memory; * after this the user just have to activate the im24-window and push the * right mouse button and im24 will open screen and windows and display the * old picture so the user can work with im24 again; * remark: by iconifying you will lose the undo-picture! * remark: the iconified-wb-window has also a closewindow-gadget, so you * can also quit im24 when it is iconified * remark: the anzeigen-flag will be cleared even if it was set */ { struct BitMap bmap; end=0; reverse(win1,1); InitBitMap(&bmap,4L,breite*aufl,hoehe); for(i=0;i<4;i++) if((bmap.Planes[i]=AllocRaster(breite*aufl,hoehe))==NULL) { for(j=0;jRPort; ClipBlit(rp3,4L,11L,rp5,0L,0L,breite*aufl,hoehe,(long)0xc0); if((win6=OpenWindow(&nw6))==NULL) { CloseWindow(win5); for(i=0;i<4;i++) if(bmap.Planes[i]) FreeRaster(bmap.Planes[i],breite*aufl,hoehe); reverse(win1,1); return(0); } SetPointer(win6,mouseptr,13L,16L,-7L,-6L); close_all(); do { while(no_msg(win6)) WaitPort(win6->UserPort); class=msg->Class; code=msg->Code; ReplyMsg(msg); if(class==VANILLAKEY) if(code=='q') class=CLOSEWINDOW; if(class==CLOSEWINDOW) if(request()) { for(i=0;i<4;i++) FreeRaster(bmap.Planes[i],breite*aufl,hoehe); CloseWindow(win6); ende(); } if(class==MOUSEBUTTONS) if(code==MENUDOWN) { if((scr=OpenScreen(&ns))==NULL) { alert(); continue; } vp=&scr->ViewPort; LoadRGB4(vp,paletteu,16L); nw1.Screen=scr; if((win1=OpenWindow(&nw1))==NULL) { close_all(); alert(); continue; } SetPointer(win1,mouseptr,13L,16L,-7L,-6L); reverse(win1,1); rp1=win1->RPort; SetAPen(rp1,1L); rectangle(rp1,xmin-1,ymin-1,xmax+1,ymax+1); for(i=0;i<16;i++) rectangle(rp1,531,11+i*11,555,20+i*11); for(i=0;i<16;i++) { SetAPen(rp1,(long)i); RectFill(rp1,532L,(long)12+i*11,554L,(long)19+i*11); } SetAPen(rp1,1L); pfeil('l',colorl); pfeil('r',colorr); nw2.Screen=scr; if((win2=OpenWindow(&nw2))==NULL) { close_all(); alert(); continue; } rp2=win2->RPort; nw3.Screen=scr; if((win3=OpenWindow(&nw3))==NULL) { close_all(); alert(); continue; } rp3=win3->RPort; BltBitMapRastPort(&bmap,0L,0L,rp3,4L,11L, breite*aufl,hoehe,(long)0xc0); for(i=0;i<4;i++) FreeRaster(bmap.Planes[i],breite*aufl,hoehe); CloseWindow(win6); anzeigen=0; update(); erase(); get_msgs(); end=1; } } while(!end); reverse(win1,1); return(1); } close_all() /* this function is closing the screen-windows and the screen to get * as much chip-memory as possible free; it also sets the window- and * screen-pointer to null, because this pointer are also flags if the * windows and the screen are open (to avoid closing them twice) */ { if(win8) CloseWindow(win8); if(win5) CloseWindow(win5); if(win3) CloseWindow(win3); if(win2) CloseWindow(win2); if(win1) CloseWindow(win1); if(scr) CloseScreen(scr); win8=win5=win3=win2=win1=scr=NULL; } request() /* this function will ask the user if he wants to quit the program; * it returns 1 if he wants to quit, 0 if not */ { int response; if(scr) { nw14.Screen=scr; nw14.Type=CUSTOMSCREEN; } else nw14.Type=WBENCHSCREEN; if((win14=OpenWindow(&nw14))==NULL) return(0); SetPointer(win14,mouseptr,13L,16L,-7L,-6L); rp14=win14->RPort; SetAPen(rp14,1L); text(rp14,32,15,"really quit the prg.?"); while(no_msg(win14)) WaitPort(win14->UserPort); class=msg->Class; code=msg->Code; gad=(struct Gadget *)msg->IAddress; ReplyMsg(msg); if(class==GADGETUP) response=gad->GadgetID==41; if(class==VANILLAKEY) response=code=='o'; CloseWindow(win14); return(response); } flood() /* this function will flood a area using the graphics.library-function; * first of all the function is waiting for a message, it is handling only * three messages: the pressing of the flood-gadget or the pressing of the * f-key to end the function immediately (e.g. when the user choose this * function and now doesn't want to flood anything) or the pushing of a * mouse button in the draw-area, then a temporary raster will be allocated * (important for the graphics.library-function) and initialized; then the * origin-size-picture will be copied in the undo-window and the draw color * will be choosed; then our temporary raster will be assigned to the ori- * gin-size-window and we will border the picture-area with an color diffe- * rent from the color under the mouse pointer (so we won't flood the whole * window) and then the graphics.library-function will be called; after this * the same (assignment and flooding) will happen to the draw-window; then * the raster-memory will be given back to the system and last the picture * will be copied to the show-window (when this exists) */ { long col,col2; struct TmpRas tras; APTR buffer=NULL; int brei,hoe; end=0; reverse(win1,3); do { while(no_msg(win1)) WaitPort(win1->UserPort); class=msg->Class; code=msg->Code; gad=(struct Gadget *)msg->IAddress; ReplyMsg(msg); if(class==MOUSEBUTTONS) if(code==SELECTDOWN || code==MENUDOWN) { xpos=win1->MouseX; ypos=win1->MouseY; if(xpos>=xmin && xpos<=xmax && ypos>=ymin && ypos<=ymax) { if((buffer=AllocRaster(640L,200L))==NULL) { reverse(win1,3); return(0); } InitTmpRas(&tras,buffer,(long)RASSIZE(640,200)); update(); xnr=(xpos-5)/(3*aufl); ynr=(ypos-12)/3; col=code==SELECTDOWN?colorl:colorr; col2=ReadPixel(rp1,(long)xpos,(long)ypos)+1; rp3->TmpRas=&tras; SetAPen(rp3,col2); brei=breite; hoe=hoehe; rectangle(rp3,3,10,4+brei*aufl,11+hoe); SetAPen(rp3,col); Flood(rp3,1L,(long)xnr*aufl+4,(long)ynr+11); rp3->TmpRas=NULL; rp1->TmpRas=&tras; SetAPen(rp1,col2); rectangle(rp1,xmin-1,ymin-1,xmax+1,ymax+1); SetAPen(rp1,col); Flood(rp1,1L,(long)xpos,(long)ypos); SetAPen(rp1,1L); rectangle(rp1,xmin-1,ymin-1,xmax+1,ymax+1); rp1->TmpRas=NULL; FreeRaster(buffer,640L,200L); if(anzeigen) ClipBlit(rp3,4L,11L,rp8,5L,12L, breite*aufl,hoehe,(long)0xc0); get_msgs(); end=1; } } if(class==GADGETUP) end=gad->GadgetID==3; if(class==VANILLAKEY) if(code=='f') { class=0; end=1; } } while(!end); reverse(win1,3); return(1); } extras() /* in the here opened extras-window the user can open the show-window, * clear the draw-area or flip and move the picture */ { reverse(win1,8); gad11.NextGadget=anzeigen?NULL:&gad10; nw7.Screen=scr; if((win7=OpenWindow(&nw7))==NULL) return(0); SetPointer(win7,mouseptr,13L,16L,-7L,-6L); rp7=win7->RPort; SetAPen(rp7,1L); rectangle(rp7,12,37,177,127); do { while(no_msg(win7)) WaitPort(win7->UserPort); class=msg->Class; code=msg->Code; gad=(struct Gadget *)msg->IAddress; ReplyMsg(msg); if(class==GADGETUP) { id=gad->GadgetID; switch(id) { case 10: if(!show()) alert(); break; case 11: clear(); break; case 12: if(!mirror()) alert(); break; case 13: if(!upside()) alert(); break; case 14: case 15: case 16: updown(id-13); break; case 17: case 18: case 19: updown(16-id); break; case 20: case 21: case 22: rightleft(id-19); break; case 23: case 24: case 25: rightleft(22-id); break; } } if(class==VANILLAKEY) switch(code) { case 's': if(!show()) alert(); break; case 'c': clear(); break; case 'h': if(!mirror()) alert(); break; case 'v': if(!upside()) alert(); break; case 'u': updown(1); break; case 'd': updown(-1); break; case 'r': rightleft(1); break; case 'l': rightleft(-1); break; case 'q': class=CLOSEWINDOW; break; } } while(class!=CLOSEWINDOW); class=0; CloseWindow(win7); reverse(win1,8); get_msgs(); return(1); } show() /* this function will open the show-window, copy the picture from the * origin-size-window and hide the show-gadget in the extras-window; * the anzeigen-flag will be set */ { int brei,hoe; nw8.Screen=scr; if((win8=OpenWindow(&nw8))==NULL) return(0); SetPointer(win8,mouseptr,13L,16L,-7L,-6L); rp8=win8->RPort; SetAPen(rp8,1L); brei=breite; hoe=hoehe; rectangle(rp8,4,11,5+brei*aufl,12+hoe); ClipBlit(rp3,4L,11L,rp8,5L,12L,breite*aufl,hoehe,(long)0xc0); anzeigen=1; gad11.NextGadget=NULL; SetAPen(rp7,0L); RectFill(rp7,15L,15L,66L,35L); return(1); } clear() /* this function is copying the actual picture in the undo-window, * then the whole drawing area is filled with the 'left color'; the * origin-size-window and the show-window are filled too */ { update(); SetAPen(rp1,(long)colorl); RectFill(rp1,(long)xmin,(long)ymin,(long)xmax,(long)ymax); SetAPen(rp3,(long)colorl); RectFill(rp3,4L,11L,3+breite*aufl,10+hoehe); if(anzeigen) { SetAPen(rp8,(long)colorl); RectFill(rp8,5L,12L,(long)4+breite*aufl,(long)11+hoehe); } } mirror() /* this function is flipping (horizonthal) the whole picture; * remark: the undo-picture gets lost */ { reverse(win7,12); nw10.Screen=scr; if((win10=OpenWindow(&nw10))==NULL) alert(); else { rp10=win10->RPort; for(i=0;iRPort; for(i=0;i0) reverse(win7,13+zahl); else reverse(win7,16-zahl); nw9.Screen=scr; if((win9=OpenWindow(&nw9))==NULL) alert(); else { rp9=win9->RPort; if(zahl>0) { ClipBlit(rp3,4L,11L,rp9,0L,0L, breite*aufl,(long)zahl,(long)0xc0); ClipBlit(rp3,4L,(long)11+zahl,rp3, 4L,11L,breite*aufl,(long)hoehe-zahl,(long)0xc0); ClipBlit(rp9,0L,0L,rp3,4L,(long)11+hoehe-zahl, breite*aufl,(long)zahl,(long)0xc0); if(anzeigen) ClipBlit(rp3,4L,11L,rp8,5L,12L,breite*aufl,hoehe,(long)0xc0); ClipBlit(rp1,5L,12L,rp9,0L,0L, breite*3*aufl,(long)zahl*3,(long)0xc0); ClipBlit(rp1,5L,(long)12+zahl*3,rp1, 5L,12L,breite*3*aufl,(long)(hoehe-zahl)*3,(long)0xc0); ClipBlit(rp9,0L,0L,rp1,5L,(long)12+(hoehe-zahl)*3, breite*3*aufl,(long)zahl*3,(long)0xc0); } else { ClipBlit(rp3,4L,(long)11+hoehe+zahl,rp9,0L,0L, breite*aufl,(long)-zahl,(long)0xc0); ClipBlit(rp3,4L,11L,rp3,4L,(long)11-zahl, breite*aufl,(long)hoehe+zahl,(long)0xc0); ClipBlit(rp9,0L,0L,rp3,4L,11L, breite*aufl,(long)-zahl,(long)0xc0); if(anzeigen) ClipBlit(rp3,4L,11L,rp8,5L,12L,breite*aufl,hoehe,(long)0xc0); ClipBlit(rp1,5L,(long)12+(hoehe+zahl)*3,rp9,0L,0L, breite*3*aufl,(long)-zahl*3,(long)0xc0); ClipBlit(rp1,5L,12L,rp1,5L,(long)12-zahl*3, breite*3*aufl,(long)(hoehe+zahl)*3,(long)0xc0); ClipBlit(rp9,0L,0L,rp1,5L,12L, breite*3*aufl,(long)-zahl*3,(long)0xc0); } update(); CloseWindow(win9); } if(zahl>0) reverse(win7,13+zahl); else reverse(win7,16-zahl); } rightleft(zahl) /* this function moves the whole picture the wished number of pixels right; * remark: the undo-picture gets lost */ int zahl; { if(zahl>0) reverse(win7,19+zahl); else reverse(win7,22-zahl); nw10.Screen=scr; if((win10=OpenWindow(&nw10))==NULL) alert(); else { rp10=win10->RPort; if(zahl>0) { ClipBlit(rp3,(long)4+(breite-zahl)*aufl,11L,rp10,0L,0L, (long)zahl*aufl,hoehe,(long)0xc0); ClipBlit(rp3,4L,11L,rp3,(long)4+(zahl*aufl),11L, (long)(breite-zahl)*aufl,hoehe,(long)0xc0); ClipBlit(rp10,0L,0L,rp3,4L,11L, (long)zahl*aufl,hoehe,(long)0xc0); if(anzeigen) ClipBlit(rp3,4L,11L,rp8,5L,12L,breite*aufl,hoehe,(long)0xc0); ClipBlit(rp1,(long)5+(breite-zahl)*3*aufl,12L,rp10,0L,0L, (long)zahl*3*aufl,hoehe*3,(long)0xc0); ClipBlit(rp1,5L,12L,rp1,(long)5+zahl*3*aufl,12L, (long)(breite-zahl)*3*aufl,hoehe*3,(long)0xc0); ClipBlit(rp10,0L,0L,rp1,5L,12L, (long)zahl*3*aufl,hoehe*3,(long)0xc0); } else { ClipBlit(rp3,4L,11L,rp10,0L,0L, (long)-zahl*aufl,hoehe,(long)0xc0); ClipBlit(rp3,(long)4-zahl*aufl,11L,rp3,4L,11L, (long)(breite+zahl)*aufl,hoehe,(long)0xc0); ClipBlit(rp10,0L,0L,rp3,(long)4+(breite+zahl)*aufl,11L, (long)-zahl*aufl,hoehe,(long)0xc0); if(anzeigen) ClipBlit(rp3,4L,11L,rp8,5L,12L,breite*aufl,hoehe,(long)0xc0); ClipBlit(rp1,5L,12L,rp10,0L,0L, (long)-zahl*3*aufl,hoehe*3,(long)0xc0); ClipBlit(rp1,(long)5-zahl*3*aufl,12L,rp1,5L,12L, (long)(breite+zahl)*3*aufl,hoehe*3,(long)0xc0); ClipBlit(rp10,0L,0L,rp1,(long)5+(breite+zahl)*3*aufl,12L, (long)-zahl*3*aufl,hoehe*3,(long)0xc0); } update(); CloseWindow(win10); } if(zahl>0) reverse(win7,19+zahl); else reverse(win7,22-zahl); } disk() /* in the by this function opened window the user can change the number of * bitplanes to be saved as source-code, he can load a palette from an iff- * file or even a whole iff-picture or save his painting in the iff-format, * moreover he can save his painting as an image-source-code in assembler * or c or, if his picture-width is only 16 pixels and he chooses 2 bitpla- * nes, as sprite-source-code in assembler or c */ { reverse(win1,5); gad28.NextGadget=(bitmaps==2 && breite==16)?&gad27:NULL; nw11.Screen=scr; if((win11=OpenWindow(&nw11))==NULL) return(0); SetPointer(win11,mouseptr,13L,16L,-7L,-6L); rp11=win11->RPort; SetAPen(rp11,1L); rectangle(rp11,66,59,177,105); reverse(win11,32+bitmaps); do { while(no_msg(win11)) WaitPort(win11->UserPort); class=msg->Class; code=msg->Code; gad=(struct Gadget *)msg->IAddress; ReplyMsg(msg); if(class==GADGETUP) { id=gad->GadgetID; switch(id) { case 26: save_a_sp(); break; case 27: save_c_sp(); break; case 28: save_a_im(); break; case 29: save_c_im(); break; case 30: load_palette(); break; case 31: if(!ilbmload()) alert(); break; case 32: if(!ilbmsave()) alert(); break; case 33: case 34: case 35: case 36: newbmaps(id-32); break; } } if(class==VANILLAKEY) switch(code) { case '1': case '2': case '3': case '4': newbmaps(code-'0'); break; case 'p': load_palette(); break; case 'l': if(!ilbmload()) alert(); break; case 's': if(!ilbmsave()) alert(); break; case 'a': save_a_im(); break; case 'c': save_c_im(); break; case 'q': class=CLOSEWINDOW; break; } } while(class!=CLOSEWINDOW); class=0; CloseWindow(win11); reverse(win1,5); get_msgs(); return(1); } newbmaps(anz) /* this function will be used when the user wants to change the number * of bitplanes to be saved; the saving of simplesprites is only possible * when you have 2 bitmaps; when the actual width is 16 and the number of * bmaps will change from or to 2 this function will also see to hide or * get the 'save-as-sprite' - gadgets; the int-variable bitmaps will be set */ int anz; { if(anz!=bitmaps) { reverse(win11,32+bitmaps); if(breite==16) if(bitmaps==2) { gad28.NextGadget=NULL; SetAPen(rp11,0L); RectFill(rp11,69L,83L,174L,103L); SetAPen(rp11,1L); } else if(anz==2) { gad28.NextGadget=&gad27; RefreshGList(&gad27,win11,NULL,2L); } bitmaps=anz; reverse(win11,32+bitmaps); } } load_palette() /* this function will ask for a filename and then load and set the color- * palette from the wished iff-file; if this iff-file does not contain * a cmap-(colormap-)chunk, the user will get informed about this; * remark: the extension .ilbm will be added */ { char ilbm_name[35]; char id[5]; long gesamt,length,gelesen; int done; unsigned char palette[32][3]; reverse(win11,30); id[4]=0; if(getname()) { strcpy(&ilbm_name,&name); strcat(&ilbm_name,".ilbm"); if((fh=Open(ilbm_name,MODE_OLDFILE))==NULL) { abort_info("can't open this file!",30); return(); } Read(fh,id,4L); if(strcmp("FORM",id)) { abort_info("not an iff file!",30); return(1); } Read(fh,&gesamt,4L); gelesen=done=0; do { if(gelesen==gesamt) { abort_info("no cmap-chunk!",30); Close(fh); return(); } else { Read(fh,id,4L); Read(fh,&length,4L); gelesen+=length+8; if(strcmp("CMAP",id)) Seek(fh,length,OFFSET_CURRENT); else done=1; } } while(!done); Read(fh,palette[0],length); for(i=0;i>4); LoadRGB4(&scr->ViewPort,paletteu,length/3); Close(fh); } reverse(win11,30); } ilbmload() /* this function will ask the user for a filename and then load and display * the wished picture; * remark: the picture can only be loaded when it has the same width, * height and depth as actually set * remark: the undo-picture gets lost * remark: the extension .ilbm will be added */ { char ilbm_name[35]; char id[5]; struct bmhd { UWORD width,height; UWORD x,y; UBYTE planes; UBYTE masking; UBYTE compr; UBYTE nop; UWORD transparent; UBYTE xprop,yprop; WORD pagewidth,pageheight; } bmhd; long length; unsigned char palette[32][3]; UWORD col[16]; long offset; reverse(win11,31); for(i=0;i>4); Read(fh,id,4L); if(strcmp("BODY",id)) { abort_info("no body-chunk!",31); return(1); } Seek(fh,4L,OFFSET_CURRENT); InitBitMap(&bmap,(long)bmhd.planes, (long)bmhd.width,(long)bmhd.height); for(i=0;i=0;i--) { for(j=0;j48) length=48; for(i=0;iViewPort,paletteu,length/3); if(aufl==1) BltBitMapRastPort(&bmap,0L,0L,rp3,4L,11L,(long)bmhd.width, (long)bmhd.height,(long)0xc0); else for(i=0;iRPort; if(aufl==1) ClipBlit(rp3,4L,11L,rp12,0L,0L,breite,hoehe,(long)0xc0); else for(i=0;i>4); Write(fh,&b,1L); b=(paletteu[i] & 0x0f0); Write(fh,&b,1L); b=((paletteu[i] & 0x00f)<<4); Write(fh,&b,1L); } b=0; for(i=16;i<32;i++) for(j=0;j<3;j++) Write(fh,&b,1L); Write(fh,"BODY",4L); l=bmap.BytesPerRow*bmap.Rows*bmap.Depth; Write(fh,&l,4L); offset=0; for(i=bmap.Rows-1;i>=0;i--) { for(j=0;jRPort; SetAPen(rp13,1L); text(rp13,14,14,"name :"); ActivateGadget(&gad37,win13,NULL); while(no_msg(win13)) WaitPort(win13->UserPort); id=((struct Gadget *)msg->IAddress)->GadgetID; ReplyMsg(msg); CloseWindow(win13); return(id==37 || id==38); } abort_info(str,nr) /* if any of the disk-functions has to be aborted, it calls this function * which displays the reason for aborting and reverses the gadget corres- * ponding to the function; at least the file will be closed if it was * open; the reason-text and the gadget-id are passed to this function as * arguments */ char *str; int nr; { nw15.Screen=scr; if((win15=OpenWindow(&nw15))==NULL) { alert(); return(); } SetPointer(win15,mouseptr,13L,16L,-7L,-6L); rp15=win15->RPort; SetAPen(rp15,2L); text(rp15,150-strlen(str)*4,15,str); WaitPort(win15->UserPort); CloseWindow(win15); reverse(win11,nr); if(fh) Close(fh); } compute() /* this function is computing the source-code-words to be saved; every * of the save-as-source-functions calls this function before saving */ { for(i=0;i<44;i++) for(j=0;j>4)][i][(k>>2)&0x03]|=(1<<(3-(k&0x03))); for(i=0;i<44;i++) for(j=0;j57) src[i][j][k]+=39; } } save_a_im() /* this function will ask the user for a filename and then save the picture * as assembler-image-source-code with the image-structure; * remark: the extension .asm will be added */ { char asm_name[34],data[4],newline=10; static unsigned char number[4][3]={"1st","2nd","3rd","4th"}; int num,nextline; reverse(win11,28); if(getname()) { strcpy(&asm_name,&name); strcat(&asm_name,".asm"); if((fh=Open(asm_name,MODE_NEWFILE))==NULL) { abort_info("can't open this file!",28); return(); } compute(); Write(fh,name,(long)strlen(name)); Write(fh,"data:",5L); Write(fh,&newline,1L); nextline=breite>128?8:(breite-1)/16+1; for(i=0;ik*16) { if(num==nextline) { Write(fh,&newline,1L); Write(fh," dc.w $",17L); num=0; } else Write(fh,", $",3L); num++; Write(fh,src[i*11+k][j],4L); } if(j==hoehe-1) { Write(fh,&newline,1L); if(i==bitmaps-1) Write(fh,&newline,1L); } } } Write(fh,name,(long)strlen(name)); Write(fh,":",1L); Write(fh,&newline,1L); Write(fh,"; struct Image:",15L); Write(fh,&newline,1L); Write(fh," dc.w 0",14L); Write(fh,&newline,1L); Write(fh," dc.w 0",14L); Write(fh,&newline,1L); ltoa(breite,data); Write(fh," dc.w ",13L); Write(fh,data,(long)strlen(data)); Write(fh,&newline,1L); ltoa(hoehe,data); Write(fh," dc.w ",13L); Write(fh,data,(long)strlen(data)); Write(fh,&newline,1L); ltoa((long)bitmaps,data); Write(fh," dc.w ",13L); Write(fh,data,(long)strlen(data)); Write(fh,&newline,1L); Write(fh," dc.l ",13L); Write(fh,name,(long)strlen(name)); Write(fh,"data",4L); Write(fh,&newline,1L); ltoa((long)(1<128?8:(breite-1)/16+1; for(i=0;ik*16) { if(num==nextline) { if(!(j==hoehe-1 && breite<=(k+1)*16)) Write(fh,",",1L); Write(fh,&newline,1L); Write(fh," 0x",10L); num=0; } else Write(fh,", 0x",4L); num++; Write(fh,src[i*11+k][j],4L); } if(j==hoehe-1) { if(i==bitmaps-1) { Write(fh," };",3L); Write(fh,&newline,1L); } else Write(fh,",",1L); Write(fh,&newline,1L); } } } Write(fh,"struct Image ",13L); Write(fh,name,(long)strlen(name)); Write(fh," =",2L); Write(fh,&newline,1L); Write(fh," { 0, 0, ",16L); ltoa(breite,data); Write(fh,data,(long)strlen(data)); Write(fh,", ",2L); ltoa(hoehe,data); Write(fh,data,(long)strlen(data)); Write(fh,", ",2L); ltoa((long)bitmaps,data); Write(fh,data,(long)strlen(data)); Write(fh,", ",2L); Write(fh,name,(long)strlen(name)); Write(fh,"data, ",6L); ltoa((long)(1<0); if(sign<0) s[i++]='-'; s[i]=0; rev_str(s); } rev_str(s) /* this function is reversing a c-string; it is used only by ltoa, * because ltoa cannot distinguish sides */ char *s; { int i,j; char c; for(i=0,j=strlen(s)-1;iRPort; SetAPen(rp16,1L); rectangle(rp16,21,75,234,90); reverse(win16,42+aufl); do { while(no_msg(win16)) WaitPort(win16->UserPort); class=msg->Class; code=msg->Code; gad=(struct Gadget *)msg->IAddress; ReplyMsg(msg); if(class==INTUITICKS) { breite=prop1.HorizPot/prop1.HorizBody+1; hoehe=prop2.HorizPot/prop2.HorizBody+1; if(aufl==1) breite=breite>166?166:breite; else breite=breite>83?83:breite; hoehe=hoehe>58?58:hoehe; ltoa(breite,brei); ltoa(hoehe,hoe); SetAPen(rp16,0L); RectFill(rp16,220L,40L,243L,47L); SetAPen(rp16,1L); text(rp16,220,40,brei); SetAPen(rp16,0L); RectFill(rp16,220L,62L,235L,69L); SetAPen(rp16,1L); text(rp16,220,62,hoe); } if(class==CLOSEWINDOW) { aufl=old_aufl; breite=old_breite; hoehe=old_hoehe; } if(class==GADGETUP) { id=gad->GadgetID; switch(id) { case 43: if(aufl==2) { aufl=1; reverse(win16,43); reverse(win16,44); breite*=2; prop1.HorizBody=0x018a; prop1.HorizPot=(USHORT)breite*prop1.HorizBody-1; RefreshGList(&gad45,win16,NULL,1L); } break; case 44: if(aufl==1) { aufl=2; reverse(win16,43); reverse(win16,44); breite/=2; prop1.HorizBody=0x0315; prop1.HorizPot=(USHORT)breite*prop1.HorizBody-1; RefreshGList(&gad45,win16,NULL,1L); } break; case 47: SetAPen(rp1,0L); RectFill(rp1,(long)xmin-1,(long)ymin-1, (long)xmax+1,(long)ymax+1); SetAPen(rp3,0L); RectFill(rp3,4L,11L, (long)3+old_breite*aufl,(long)10+old_hoehe); if(anzeigen) { SetAPen(rp8,0L); RectFill(rp8,4L,11L,5+old_breite*old_aufl,12+old_hoehe); breit=breite; hoeh=hoehe; SetAPen(rp8,1L); rectangle(rp8,4,11,5+breit*aufl,12+hoeh); } xmax=4+breite*3*aufl; ymax=11+hoehe*3; SetAPen(rp1,1L); rectangle(rp1,xmin-1,ymin-1,xmax+1,ymax+1); class=CLOSEWINDOW; break; case 48: aufl=old_aufl; breite=old_breite; hoehe=old_hoehe; class=CLOSEWINDOW; break; } } if(class==VANILLAKEY) if(code=='q') { aufl=old_aufl; breite=old_breite; hoehe=old_hoehe; class=CLOSEWINDOW; } } while(class!=CLOSEWINDOW); class=0; CloseWindow(win16); reverse(win1,7); get_msgs(); return(1); } colors() /* in the from this function opened window the user can edit the colors; * he can then accept his new palette, take the palette before or simple * reset the palette to the palette which was at the beginning of the * program */ { UWORD palettes[16]; char r[2],g[2],b[2]; USHORT re,gr,bl; int col; reverse(win1,6); for(i=0;i<16;i++) palettes[i]=paletteu[i]; r[1]=g[1]=b[1]=0; prop3.HorizPot=((paletteu[colorl]>>8)&0xf)*0x1000+0x0800; prop4.HorizPot=((paletteu[colorl]>>4)&0xf)*0x1000+0x0800; prop5.HorizPot=(paletteu[colorl]&0xf)*0x1000+0x0800; nw17.Screen=scr; if((win17=OpenWindow(&nw17))==NULL) { reverse(win1,6); return(0); } SetPointer(win17,mouseptr,13L,16L,-7L,-6L); rp17=win17->RPort; SetAPen(rp17,1L); rectangle(rp17,12,15,117,56); do { while(no_msg(win17)) WaitPort(win17->UserPort); class=msg->Class; code=msg->Code; gad=(struct Gadget *)msg->IAddress; ReplyMsg(msg); if(class==INTUITICKS) { re=prop3.HorizPot/0x1000; gr=prop4.HorizPot/0x1000; bl=prop5.HorizPot/0x1000; paletteu[colorl]=(re<<8)+(gr<<4)+bl; SetRGB4(vp,(long)colorl,(long)re,(long)gr,(long)bl); r[0]=re>9?re+'a'-10:re+'0'; g[0]=gr>9?gr+'a'-10:gr+'0'; b[0]=bl>9?bl+'a'-10:bl+'0'; SetAPen(rp17,0L); RectFill(rp17,298L,18L,305L,25L); SetAPen(rp17,1L); text(rp17,298,18,r); SetAPen(rp17,0L); RectFill(rp17,298L,31L,305L,38L); SetAPen(rp17,1L); text(rp17,298,31,g); SetAPen(rp17,0L); RectFill(rp17,298L,44L,305L,51L); SetAPen(rp17,1L); text(rp17,298,44,b); } if(class==GADGETUP) { ; id=gad->GadgetID; switch(id) { case 49: class=CLOSEWINDOW; break; case 50: for(i=0;i<16;i++) paletteu[i]=palettes[i]; LoadRGB4(vp,paletteu,16L); class=CLOSEWINDOW; break; case 51: for(i=0;i<16;i++) paletteu[i]=paletteb[i]; LoadRGB4(vp,paletteu,16L); class=CLOSEWINDOW; break; } } if(class==VANILLAKEY) switch(code) { case 'b': col=(colorl-1)&0xf; new_color('l',col); prop3.HorizPot=((paletteu[colorl]>>8)&0xf)*0x1000+0x0800; prop4.HorizPot=((paletteu[colorl]>>4)&0xf)*0x1000+0x0800; prop5.HorizPot=(paletteu[colorl]&0xf)*0x1000+0x0800; RefreshGList(&gad54,win17,NULL,3L); break; case 'n': col=(colorl+1)&0xf; new_color('l',col); prop3.HorizPot=((paletteu[colorl]>>8)&0xf)*0x1000+0x0800; prop4.HorizPot=((paletteu[colorl]>>4)&0xf)*0x1000+0x0800; prop5.HorizPot=(paletteu[colorl]&0xf)*0x1000+0x0800; RefreshGList(&gad54,win17,NULL,3L); break; case 'q': class=CLOSEWINDOW; break; } } while(class!=CLOSEWINDOW); class=0; CloseWindow(win17); reverse(win1,6); get_msgs(); return(1); }