/* ------------------------------------------------------------------------- */ /* "infoclues": A small utility to convert (simple) UHS-format hints into */ /* an Inform include file which runs an "Invisiclues"-style */ /* menu (with submenus) of hints */ /* */ /* (C) Copyright Graham Nelson, 1994, 1995 */ /* */ /* For use with Inform 5 */ /* ------------------------------------------------------------------------- */ #include #include #include #include typedef struct menu_item_s { char t[256]; } menu_item; typedef struct menu_s { char name[32]; char title[256]; menu_item items[32]; int menu_size; } menu; typedef struct subj_s { char name[256]; } subj; FILE *ifp; FILE *ofp; char *process(char *s) { int i; for (i=0; s[i]!=0; i++) { if (s[i]=='\"') s[i]='~'; if ((s[i]=='\\')||(s[i]=='@')) s[i]='?'; } i=0; while (s[i]==' ') i++; return(s+i); } int max_size = 12, max_width = 72; menu main_menu, sub_menu, next_menu; void compile_menu(menu *M) { int i, flag=0; if (M->menu_size > max_size+1) { sprintf(next_menu.name, "%sN", M->name); sprintf(next_menu.title, "%s (2)", M->title); next_menu.menu_size = 0; for (i=max_size; imenu_size; i++, next_menu.menu_size++) next_menu.items[i-max_size] = M->items[i]; M->menu_size = max_size+1; sprintf(M->items[max_size].t, ">> To next page"); flag=1; fprintf(ofp, "[ %s_Info i;\n", next_menu.name); fprintf(ofp, " menu_item=menu_item+%d; i=%s_Info(menu_item);\n", max_size, M->name); fprintf(ofp, " menu_item=menu_item-%d; return i;\n", max_size); fprintf(ofp, "];\n\n"); } for (i=0; imenu_size; i++) { process(M->items[i].t); if (strlen(M->items[i].t) > max_width) sprintf(M->items[i].t + max_width-4, " ..."); } fprintf(ofp, "[ %s_Menu;\n", M->name); fprintf(ofp, " DoMenu(\"^\\\n"); for (i=0; imenu_size; i++) fprintf(ofp, " ^ %s\\\n", M->items[i].t); fprintf(ofp, " ^\", #r$%s_TR, #r$%s_Info%s);\n", M->name, M->name, (flag==0)?"":"X"); fprintf(ofp, "];\n\n"); fprintf(ofp, "[ %s_TR;\n", M->name); fprintf(ofp, " if (menu_item==0) { item_name=\"%s\"; item_width=%d; return %d; }\n", M->title, strlen(M->title)/2, M->menu_size); for (i=0; imenu_size; i++) fprintf(ofp, " if (menu_item==%d) { item_name=\"%s\"; item_width=%d; }\n", i+1, M->items[i].t, strlen(M->items[i].t)/2); fprintf(ofp, "];\n\n"); if (flag==1) { fprintf(ofp, "[ %s_InfoX;\n", M->name); fprintf(ofp, " if (menu_item == %d) { %sN_Menu(); return 2; }\n", M->menu_size, M->name); fprintf(ofp, " return %s_Info(menu_item);\n", M->name); fprintf(ofp, "];\n\n"); compile_menu(&next_menu); } } subj the_subjects[64]; void prologue(void) { fprintf(ofp, "! Clues file generated automatically from UHS source\n\n"); fprintf(ofp, "[ GiveHint hint flag keypress;\n"); fprintf(ofp, " if (flag==1) print \"(Press H for another hint, or SPACE to return.)^^\";"); fprintf(ofp, " print_paddr hint;\n"); fprintf(ofp, " new_line; new_line;\n"); fprintf(ofp, " @read_char 1 0 0 keypress;\n"); fprintf(ofp, " if (keypress == 'H' or 'h') rfalse;\n"); fprintf(ofp, " rtrue;\n"); fprintf(ofp, "];\n\n"); } void epilogue(void) { int i; menu *M=&main_menu; fprintf(ofp, "[ Main_Info;\n"); for (i=0; imenu_size; i++) fprintf(ofp, " if (menu_item == %d) Subj%d_Menu();\n", i+1, i+1); fprintf(ofp, " return 2;\n\n"); fprintf(ofp, "];\n\n"); compile_menu(M); } char hintbuff[2048]; int in_sr_flag=0; void finish_subject(void) { if (in_sr_flag!=1) return; in_sr_flag=0; fprintf(ofp, "];\n\n"); } int in_hint_flag=0; void finish_hint(void) { if (in_hint_flag!=1) return; if (strlen(hintbuff)!=0) { fprintf(ofp, " \"%s\";\n", process(hintbuff)); hintbuff[0]=0; } in_hint_flag=0; fprintf(ofp, " }\n"); } int main(int argc, char **argv) { char buffer[256], fw[256]; int hints=0, i, j, k, given; printf("Infoclues 1: Generates clues-menu Inform code from UHS source\n"); if (argc!=3) { printf("Syntax is: infoclues fromfile tofile\n"); exit(1); } ifp = fopen(argv[1], "r"); if (ifp==NULL) { printf("Input file won't open\n"); exit(1); } ofp = fopen(argv[2], "w"); if (ofp==NULL) { printf("Output file won't open\n"); exit(1); } prologue(); main_menu.menu_size = 0; strcpy(main_menu.title, "Clues"); strcpy(main_menu.name, "Main"); hintbuff[0]=0; while (feof(ifp)==0) { if (fgets(buffer,256,ifp)==0) goto RunOut; for (i=0; buffer[i]==' '; i++) ; for (j=i; buffer[j]!=' ' && buffer[j]!=0; j++) fw[j-i]=buffer[j]; fw[j-i]=0; while (buffer[j]==' ') j++; for (k=0; buffer[k]!=0; k++) if (buffer[k]=='\n') buffer[k]=0; if ((fw[0]=='[') && (fw[strlen(fw)-1]==']')) { if (strcmp(fw, "[subject]")==0) { strcpy(main_menu.items[main_menu.menu_size++].t, buffer+j); if (in_sr_flag==1) { finish_hint(); finish_subject(); compile_menu(&sub_menu); } in_sr_flag=1; fprintf(ofp, "[ Subj%d_Info;\n", main_menu.menu_size); sub_menu.menu_size = 0; strcpy(sub_menu.title, buffer+j); sprintf(sub_menu.name, "Subj%d", main_menu.menu_size); } else { strcpy(sub_menu.items[sub_menu.menu_size++].t, buffer+j); hints++; finish_hint(); fprintf(ofp, " if (menu_item==%d) {\n", sub_menu.menu_size); in_hint_flag=1; given=0; } } else if (strcmp(fw, ">>")==0) { if (strlen(hintbuff)!=0) { fprintf(ofp, " if (GiveHint(\"%s\"%s)==1) return 2;\n", process(hintbuff), (given++==0)?",1":""); } strcpy(hintbuff, buffer+j); } else { sprintf(hintbuff+strlen(hintbuff), " %s", buffer+i); } } RunOut: fclose(ifp); if (in_sr_flag==1) { finish_hint(); finish_subject(); compile_menu(&sub_menu); } epilogue(); fclose(ofp); printf("Completed: %d subjects, %d hints\n", main_menu.menu_size, hints); return(0); }