/* Men˙.c V1.0 *********** Author: Teijo Kinnunen Oksantie 19 FIN-86300 OULAINEN FINLAND Date: 30.05.1994 Status: Copyright 1994 Teijo Kinnunen. All rights reserved. Freely Distributable, along with the rest of the Men˙ package. Modified versions of this file and/or the executable program may not be distributed! (Contact the author if you have made improvements that you would like to share with other users, YOU may NOT release altered prog!.) */ #include #include #include #include #include #include #include #include #include #include #include #include ULONG LOGOHEIGHT; #define C_TITLE 1 #define C_ITEM 2 #define C_HDR 3 #define C_SECCOL 4 #define C_ENDM 5 #define C_MENU 6 #define C_SUBM 7 #define C_ITEMQ 8 #define C_WITEM 9 #define C_WMENU 10 #define C_WITEMQ 11 #define C_ISSUE 12 #define C_PICTURE 13 #define C_PICHEIGHT 14 #define C_PICWIDTH 15 #define C_PICDEPTH 16 struct Image logo; WORD frame_wht[] = { 312,0,0,0,0,13,1,12,1,1 }, frame_blk[] = { 1,13,312,13,312,0,311,1,311,12 }; WORD wframe_wht[] = { 625,0,0,0,0,13,1,12,1,1 }, wframe_blk[] = { 1,13,625,13,625,0,624,1,624,12 }; WORD mframe_wht[] = { 287,0,0,0,0,13,1,12,1,1 }, mframe_blk[] = { 1,13,287,13,287,0,286,1,286,12 }; WORD qframe_wht[] = { 49,0,0,0,0,13,1,12,1,1 }, qframe_blk[] = { 1,13,49,13,49,0,48,1,48,12 }; struct Border brd[] = { { 0,0,2,0,JAM1,5,frame_wht,&brd[1] }, { 0,0,1,0,JAM1,5,frame_blk,0L }, { 0,0,2,0,JAM1,5,wframe_wht,&brd[3] }, { 0,0,1,0,JAM1,5,wframe_blk,0L }, { 0,0,2,0,JAM1,5,qframe_wht,&brd[5] }, { 0,0,1,0,JAM1,5,qframe_blk,0L }, { 0,0,2,0,JAM1,5,mframe_wht,&brd[7] }, { 0,0,1,0,JAM1,5,mframe_blk,0L } }; struct Border hibrd[] = { // inversed borders { 0,0,1,0,JAM1,5,frame_wht,&hibrd[1] }, { 0,0,2,0,JAM1,5,frame_blk,0L }, { 0,0,1,0,JAM1,5,wframe_wht,&hibrd[3] }, { 0,0,2,0,JAM1,5,wframe_blk,0L }, { 0,0,1,0,JAM1,5,qframe_wht,&hibrd[5] }, { 0,0,2,0,JAM1,5,qframe_blk,0L }, { 0,0,1,0,JAM1,5,mframe_wht,&hibrd[7] }, { 0,0,2,0,JAM1,5,mframe_blk,0L } }; struct TextAttr t80 = { "topaz.font",8,0,0 }; struct IntuiText t[] = { { 1,0,JAM2,98-25,3,&t80,"« PARENT MENU",0 }, { 1,0,JAM2,102-25,3,&t80,"«« MAIN MENU",0 }, { 2,0,JAM2,4,3,&t80,"»",0 }, { 1,0,JAM2,0,0,&t80,0,&t[4] }, { 2,0,JAM1,-2,-1,&t80,0,0 }, { 1,0,JAM2,550,3,NULL,0 }, // Issue { 1,0,JAM1,9,3,&t80,"Quit",0 } }; struct Gadget g[] = { { &g[1],10,175,288,14,GFLG_GADGHIMAGE|GFLG_DISABLED,GACT_RELVERIFY,GTYP_BOOLGADGET, &brd[6],&hibrd[6],&t[0],0,0,999,0L }, { &g[2],298,175,288,14,GFLG_GADGHIMAGE|GFLG_DISABLED,GACT_RELVERIFY,GTYP_BOOLGADGET, &brd[6],&hibrd[6],&t[1],0,0,998,0L }, { NULL,298+288,175,50,14,GFLG_GADGHIMAGE,GACT_RELVERIFY,GTYP_BOOLGADGET, &brd[4],&hibrd[4],&t[6],0,0,997,0L } }; UWORD scrpens[] = { (UWORD)~0 }; struct TagItem scrtags[] = { { SA_Pens,(ULONG)scrpens }, { SA_PubName,(ULONG)"Men˙_Screen" }, { SA_PubSig,0 }, { TAG_DONE } }; struct ExtNewScreen ns = { 0,0,640,STDSCREENHEIGHT,2,0,1,HIRES|SPRITES,CUSTOMSCREEN|NS_EXTENDED, &t80,"Men˙ V1.0 Copyright 1994 Teijo Kinnunen",NULL,NULL,scrtags }; struct NewWindow nw = { 0,0,640,200,0xFF,0xFF,IDCMP_GADGETUP, WFLG_BACKDROP|WFLG_BORDERLESS|WFLG_SMART_REFRESH|WFLG_ACTIVATE|WFLG_NOCAREREFRESH|WFLG_RMBTRAP, &g[0],0,0L,0L,0L, 0,0,0,0,CUSTOMSCREEN }; long dispx = 10; #define MAX_LINES 1000 struct Remember *gadgs; long lines,menutop,currmenu,topmostitem,currpar,menubot; UWORD parents[15],issuedsp = 0; BPTR out; struct Window *w; struct Screen *s; char *line[MAX_LINES],*verstag = "$VER: Men˙ 1.0 (30.05.94)"; void HandleMenu(void),DspMenu(void),UseMenu(LONG); BOOL HandleGadget(UWORD); BYTE pubscrsig = -1; APTR picturedata; LONG picturelen; LONG GetCmd(char *); char *GetArg(char *); void msg(char *msg) { Write(out,msg,strlen(msg)); } ULONG asc_to_long(char *num) { ULONG result = 0; while(*num >= '0' && *num <= '9') { result *= 10; result += *num++ - '0'; } return(result); } BOOL ReadFile(char *name) { char temp[260]; FILE *fp; BOOL err = TRUE; fp = fopen(name,"r"); if(!fp) { msg("Can't open script.\n"); goto xrd0; } while(fgets(temp,256,fp)) { if(lines > MAX_LINES) { lines = MAX_LINES; msg("Line buffer overflow!\n"); goto xrd1; } if(!(line[lines] = (char *)malloc(strlen(temp)+2))) { msg("Out of memory!\n"); goto xrd1; } if(strlen(temp)) temp[strlen(temp) - 1] = 0; strcpy(line[lines++],temp); } err = FALSE; xrd1: fclose(fp); xrd0: return(err); } void main(int argc,char **argv) { out = Output(); pubscrsig = AllocSignal(-1); if(pubscrsig == -1) { msg("No signal!\n"); goto done; } scrtags[2].ti_Data = (ULONG)pubscrsig; if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))) { msg("No intuition.library!\n"); goto done; } if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))) { msg("No graphics.library!\n"); goto done; } if(argc < 2 || ReadFile(argv[1])) goto done; /* check if a picture descriptor exists */ if(lines >= 4) { char *widstr,*heistr,*namestr,*depstr; ULONG wid,hei,dep; if(GetCmd(line[0]) == C_PICTURE && GetCmd(line[1]) == C_PICWIDTH && GetCmd(line[2]) == C_PICHEIGHT && GetCmd(line[3]) == C_PICDEPTH && (widstr = GetArg(line[1])) && (heistr = GetArg(line[2])) && (namestr = GetArg(line[0])) && (depstr = GetArg(line[3]))) { FILE *picf; wid = asc_to_long(widstr); hei = asc_to_long(heistr); dep = asc_to_long(depstr); if(wid && hei && (picf = fopen(namestr,"r"))) { LONG len; fseek(picf,0,SEEK_END); len = ftell(picf); rewind(picf); if(picturedata = AllocMem(picturelen = len,MEMF_PUBLIC|MEMF_CHIP)) { if(fread(picturedata,picturelen,1,picf) != 1) { FreeMem(picturedata,picturelen); picturedata = 0; } else { UBYTE planep = 0; logo.ImageData = picturedata; logo.Width = wid; LOGOHEIGHT = logo.Height = hei; logo.Depth = dep; if(dep > 2) ns.Depth = dep; while(dep--) { planep <<= 1; planep |= 1; } logo.PlanePick = planep; } } fclose(picf); } } } if(!(s = OpenScreen((struct NewScreen *)&ns))) { msg("Can't open screen.\n"); goto done; } if(IntuitionBase->LibNode.lib_Version >= 36) PubScreenStatus(s,0); nw.Screen = s; g[0].TopEdge += s->BarHeight; g[1].TopEdge += s->BarHeight; g[2].TopEdge += s->BarHeight; if(!(w = OpenWindow(&nw))) { msg("Can't open window.\n"); goto done; } if(picturedata) DrawImage(w->RPort,&logo,0,s->BarHeight + 2); HandleMenu(); done: if(w) CloseWindow(w); if(s) { if(IntuitionBase->LibNode.lib_Version >= 36) { while(!CloseScreen(s)) Wait(1<UserPort); while(msg = (struct IntuiMessage *)GetMsg(w->UserPort)) { class = msg->Class; gadp = (struct Gadget *)msg->IAddress; ReplyMsg((struct Message *)msg); } if(class == IDCMP_GADGETUP) { if(gadp->GadgetID < 500) { if(HandleGadget(gadp->GadgetID)) return; } else if(gadp->GadgetID == 998) { currpar = 0; UseMenu(0); } else if(gadp->GadgetID == 999) { if(currpar) UseMenu(parents[--currpar]); } else if(gadp->GadgetID == 997) return; } } } LONG GetCmd(char *ln) { static char *cmdtbl[] = { "title","item","hdr","seccol","endm","menu","subm","itemq","witem", "wmenu","witemq","issue","picture","picheight","picwidth","picdepth",0 }; register LONG cnt = 1; char cmdbuff[260]; register char *to = cmdbuff,**ctp; while(*ln != ' ' && *ln != '\t' && *ln) *to++ = *ln++; *to = 0; ctp = cmdtbl; while(*ctp) if(!stricmp(*ctp,cmdbuff)) return(cnt); else { ctp++; cnt++; } return(0); } char *GetArg(char *ln) { while(*ln != ' ' && *ln != '\t' && *ln) ln++; if(*ln == ' ' || *ln == '\t') ln++; if(!(*ln)) return 0; else return(ln); } void CreateGadg(UWORD left,UWORD top,char *text,ULONG line,BOOL menu,BOOL wide) { register long txtlen = strlen(text); register struct Gadget *gad = (struct Gadget *)AllocRemember(&gadgs,sizeof (struct Gadget),MEMF_PUBLIC|MEMF_CLEAR); register struct IntuiText *txt = (struct IntuiText *)AllocRemember(&gadgs, sizeof(struct IntuiText),MEMF_PUBLIC|MEMF_CLEAR); if(!gad || !txt) return; gad->LeftEdge = left; gad->TopEdge = top; gad->Width = wide ? 626 : 313; gad->Height = 14; gad->Flags = GADGHIMAGE; gad->Activation = RELVERIFY; gad->GadgetRender = (wide ? &brd[2] : &brd[0]); gad->SelectRender = (wide ? &hibrd[2] : &hibrd[0]); gad->GadgetType = BOOLGADGET; gad->GadgetText = txt; gad->GadgetID = line; txt->FrontPen = 1; txt->DrawMode = JAM2; txt->TopEdge = 3; txt->LeftEdge = (wide ? 310 : 150) - (txtlen * 4); txt->ITextFont = &t80; txt->IText = text; if(menu) txt->NextText = &t[2]; AddGadget(w,gad,-1); } BOOL SkipVert(void) { menutop += 14; if(menutop > 170) { if(dispx == 10) { dispx = 323; menutop = topmostitem; } else return(TRUE); } return(FALSE); } void DspMenu() { register LONG l,cmd,x; register char *li,*arg; topmostitem = menutop = s->BarHeight + LOGOHEIGHT + 3; menubot = 0; dispx = 10; for(l = currmenu; l < lines; l++) { li = line[l]; cmd = GetCmd(li); arg = GetArg(li); switch(cmd) { case C_TITLE: if(menutop <= 168) { if(arg) { if((x = strlen(arg)) >= 78) break; } else x = 0; if(menutop < menubot) menutop = menubot; if(x) { t[3].IText = arg; t[4].IText = arg; PrintIText(w->RPort,&t[3],320 - (x * 4),menutop + 3); } menutop += 14; topmostitem = menutop; dispx = 10; if(menutop > menubot) menubot = menutop; } break; case C_ITEMQ: case C_ITEM: case C_MENU: case C_WMENU: case C_WITEM: case C_WITEMQ: if(arg) { register BOOL wide = (cmd == C_WMENU || cmd == C_WITEM || cmd == C_WITEMQ); x = strlen(arg); if(wide) { if(x >= 78) break; dispx = 10; if(menutop < menubot) menutop = menubot; } else if(x >= 38) break; CreateGadg(dispx,menutop,arg,l,(cmd == C_MENU || cmd == C_WMENU) ? TRUE : FALSE, wide); if(wide) { if((menutop += 14) > 170) goto xdisp; topmostitem = menutop; } else if(SkipVert()) goto xdisp; if(menutop > menubot) menubot = menutop; } break; case C_HDR: if(arg && (x = strlen(arg)) < 38) { t[3].IText = arg; t[4].IText = arg; PrintIText(w->RPort,&t[3],dispx + 150 - (x * 4),menutop + 3); if(SkipVert()) goto xdisp; if(menutop > menubot) menubot = menutop; } break; case C_SECCOL: if(dispx == 10) { dispx = 323; menutop = topmostitem; } break; case C_ENDM: goto xdisp; case C_ISSUE: if(!issuedsp) { t[5].IText = arg; PrintIText(w->RPort,&t[5],0,s->BarHeight); issuedsp = 1; } break; } } xdisp: RefreshGadgets(&g[0],w,0L); } BOOL HandleGadget(UWORD gid) { register char *ln,*mname,*n2; register LONG cmd,lc; if(gid >= lines) return(FALSE); ln = line[gid]; cmd = GetCmd(ln); if(cmd == C_ITEM || cmd == C_ITEMQ || cmd == C_WITEM || cmd == C_WITEMQ) { for(lc = gid + 1; lc < lines; lc++) { ln = line[lc]; if(!ln || !(*ln) || GetCmd(ln)) break; if(!stricmp(ln,"WBToFront")) WBenchToFront(); else if(!stricmp(ln,"MenuToFront")) ScreenToFront(s); else Execute(ln,0,out); } if(cmd == C_ITEMQ || cmd == C_WITEMQ) return(TRUE); } else if(cmd == C_MENU || cmd == C_WMENU) { if(gid++ < lines && !GetCmd(line[gid])) { mname = line[gid]; for(lc = 0; lc < lines; lc++) { if(GetCmd(line[lc]) == C_SUBM) { n2 = GetArg(line[lc]); if(!stricmp(n2,mname)) { if(currpar < 14) parents[currpar++] = currmenu; UseMenu(lc); break; } } } if(lc == lines) DisplayBeep(0); } } return(FALSE); } void UseMenu(LONG line) { register WORD rempos; currmenu = line; RemoveGList(w,g[2].NextGadget,-1); if(gadgs) FreeRemember(&gadgs,TRUE); gadgs = 0; rempos = RemoveGList(w,&g[0],3); SetAPen(w->RPort,0); RectFill(w->RPort,w->BorderLeft,s->BarHeight+LOGOHEIGHT+3, w->Width - w->BorderRight,w->Height - w->BorderBottom); if(currpar) g[0].Flags &= ~GFLG_DISABLED; else g[0].Flags |= GFLG_DISABLED; if(currmenu) g[1].Flags &= ~GFLG_DISABLED; else g[1].Flags |= GFLG_DISABLED; if(rempos >= 0) AddGList(w,&g[0],rempos,3,NULL); DspMenu(); }