/* ------------------------------------------------------------------------- */
/* "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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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; i<M->menu_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; i<M->menu_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; i<M->menu_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; i<M->menu_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; i<M->menu_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);
}