/* wincvt.c ** ** by Wayne E. Wright, W5XD ** Round Rock, Tx ** June, 1992 ** ** This utility converts Atari ST resource files (.RSC) into ** Windows resource files (.RC). ** ** The conversion is not perfect, but its purpose is to aid in porting ** a GEM program to Windows. At least the geometry comes out the same ** and all the text comes out in the right place. ** ** It does not convert bit maps at all, nor does it convert BOXCHARs. ** ** ** To convert a file (actually a .RSC/.DEF file pair), run the program with ** the file name as its argument--with no dot and no extension. ** ** The program is designed to read .DEF files generated by Laser C. I ** don't know if it works with other resource editors. It does still ** make a conversion without a .DEF file, but with no symbols the .RC ** file is of limited usefulness. ** ** The result of the conversion is a .RC file (which is text) and a ** .H file. Note that this header file has the same symbols in it as the ** the Atari resource editor's equivalent H file--but the values of the ** symbols are not at all the same. ** ** The RC file then can be edited by Windows development tools to get the ** exact behavior you want under Windows. ** ** Note that this program must itself run on the Atari because the byte ** it uses binary reads to get the int's out of the RSC file. This could ** be written in a portable way so that you could copy the RSC/DEF files ** to the PC world and run this program there, but I still have an ** Atari and I'm lazy. ** */ #include #include #include #include struct DefFileEntry { int TreeNumber; int ObjIndex; unsigned Flag; char Label[8]; }; struct DefLabel { struct DefFileEntry Entry; int MenuFlag; }; static int NumLabels; static struct DefLabel *LabelArray; static FILE *RcFile; #define RBUTTON_ID_START 20 /* beginning ID for radio buttons */ #define MAX_RBTN_BOX 20 /* maximum # of radio btns in a box */ #define ID_START 256 static int RadioBtnIdx = RBUTTON_ID_START; main(argc,argv) char *argv[]; { RSHDR RscHeader; OBJECT *ObjectPtr; TEDINFO *TextPtr; OBJECT **TreeIndex; FILE *RscFile; FILE *DefFile; char *ReadBuffer; register int i,j; int TreeCount; int *LabelReference; char InRscFile[80]; char OutHfile[80]; char OutRCfile[80]; char InDefFile[80]; puts("Convert to MS Windows 3.0 Resource\n"); if (argc < 2) { puts("Usage: rscfile\n"); puts(" Will read rscfile.rsc and rscfile.def and create\n"); puts(" rscfile.h and rscfile.rc\n"); exit(0); } strcpy(InRscFile, argv[1]); strcat(InRscFile, ".RSC"); strcpy(OutHfile, argv[1]); strcat(OutHfile, ".H"); strcpy(OutRCfile, argv[1]); strcat(OutRCfile, ".RC"); strcpy(InDefFile, argv[1]); strcat(InDefFile, ".DEF"); RscFile = fopen(InRscFile, "br"); if (RscFile == NULL) { printf("can't open %s\n", InRscFile); exit(0); } RcFile = fopen(OutRCfile, "w"); if (!RcFile) { printf("Can't open output file :%s\n", OutRCfile); exit(0); } fprintf(RcFile, "#include \"%s\"\n", OutHfile); DefFile = fopen(InDefFile, "br"); if (!DefFile) { printf("Can't open %s\nContinuing...\n", InDefFile); } NumLabels = 0; if (DefFile) { fseek(DefFile, 9l, 0); fread(&NumLabels, 1, 2, DefFile); LabelArray = (struct DefLabel *) malloc( NumLabels * sizeof(*LabelArray)); for (i = 0; i < NumLabels; i += 1) { fread(LabelArray + i, sizeof(struct DefFileEntry), 1, DefFile); LabelArray[i].MenuFlag = -1; } fclose(DefFile); } if (fread(&RscHeader, sizeof(RscHeader), 1, RscFile) <= 0) { printf("Can't read header\n"); exit(0); } ReadBuffer = malloc(RscHeader.rsh_rssize); rewind(RscFile); if (fread(ReadBuffer, 1, RscHeader.rsh_rssize, RscFile) != RscHeader.rsh_rssize) { printf("File read failure\n"); exit(0); } fclose(RscFile); /* Get index of tedinfos */ TextPtr = (TEDINFO *) (((long)ReadBuffer) + RscHeader.rsh_tedinfo); ObjectPtr = (OBJECT *) (((long)ReadBuffer) + RscHeader.rsh_object); TreeIndex = (OBJECT **) (((long)ReadBuffer) + RscHeader.rsh_trindex); i = 0; while (i < RscHeader.rsh_nted) { TextPtr->te_ptext += (long) ReadBuffer; TextPtr->te_ptmplt += (long) ReadBuffer; TextPtr->te_pvalid += (long) ReadBuffer; TextPtr++; i += 1; } i = 0; while ((char *) &TreeIndex[i] < ReadBuffer + RscHeader.rsh_rssize) { TreeIndex[i] = (OBJECT *)((long) ReadBuffer + (char *) TreeIndex[i]); i += 1; } TreeCount = i; for (i = 0; i < RscHeader.rsh_nobs; i += 1) { switch(ObjectPtr->ob_type) { case G_STRING: case G_BUTTON: case G_TITLE: case G_TEXT: case G_BOXTEXT: case G_FTEXT: case G_FBOXTEXT: if (ObjectPtr->ob_spec) ObjectPtr->ob_spec += (long) ReadBuffer; break; default: break; } /* convert to Windows style coordinates */ j = (ObjectPtr->ob_x >> 8) & 0xFF; ObjectPtr->ob_x &= 0xFF; ObjectPtr->ob_x *= 4; ObjectPtr->ob_x += j >> 1; j = (ObjectPtr->ob_y >> 8) & 0xFF; ObjectPtr->ob_y &= 0xFF; ObjectPtr->ob_y *= 8; ObjectPtr->ob_y += j >> 1; j = (ObjectPtr->ob_width >> 8) & 0xFF; ObjectPtr->ob_width &= 0xFF; ObjectPtr->ob_width *= 4; ObjectPtr->ob_width += j >> 1; j = (ObjectPtr->ob_height >> 8) & 0xFF; ObjectPtr->ob_height &= 0xFF; ObjectPtr->ob_height *= 8; ObjectPtr->ob_height += j >> 1; ObjectPtr++; } for (i = 0; i < TreeCount; i += 1) { ProcessObjTree(TreeIndex[i], i); } if (DefFile) DefFile = fopen(OutHfile, "w"); if (DefFile) { for (i = 0; i < NumLabels; i += 1) { char UserLabel[10]; bzero(UserLabel, sizeof(UserLabel)); strncpy(UserLabel,LabelArray[i].Entry.Label, sizeof(LabelArray[0].Entry.Label)); j = (LabelArray[i].MenuFlag == -1) ? i + ID_START : LabelArray[i].MenuFlag; fprintf(DefFile, "#define %s %d\n", UserLabel, j); } fclose(DefFile); } fclose(RcFile); return 0; } static struct DefFileEntry *FindObjLabel(LabelArray, NumLabels, TreeIndex, ObIndex) register struct DefLabel *LabelArray; register int NumLabels; register int TreeIndex; register int ObIndex; { while (NumLabels--) { if ((LabelArray->Entry.TreeNumber == TreeIndex) && (LabelArray->Entry.ObjIndex == ObIndex) && (LabelArray->Entry.Flag >= 256)) return &LabelArray->Entry; LabelArray += 1; } return NULL; } static struct DefFileEntry *FindTreeLabel(LabelArray, NumLabels, TreeIndex) register struct DefLabel *LabelArray; register int NumLabels; register int TreeIndex; { while (NumLabels--) { if ((LabelArray->Entry.Flag < 256) && (LabelArray->Entry.ObjIndex == TreeIndex)) return &LabelArray->Entry; LabelArray += 1; } return NULL; } static int AddGroupStop = 0; PrChildren(Tree,TreeIndex, Parent, xParent, yParent) register OBJECT *Tree; int TreeIndex; register int Parent; int xParent; int yParent; { register int i; struct DefLabel *Label; char UserLabel[10]; TEDINFO *Ted; int SavedRBtnIdx; int TmpRBtnIdx; int FirstRButton; i = Tree[Parent].ob_head; SavedRBtnIdx = RadioBtnIdx; FirstRButton = 1; while (i != Parent) { bzero(UserLabel, sizeof(UserLabel)); Label = (struct DefLabel *)FindObjLabel(LabelArray, NumLabels, TreeIndex, i); if (Label) { strncpy(UserLabel, Label->Entry.Label, sizeof(Label->Entry.Label)); UserLabel[sizeof(Label->Entry.Label)] = 0; } else strcpy(UserLabel, "-1"); switch(Tree[i].ob_type) { case G_BOX: case G_IBOX: if (Tree[i].ob_head >= 0) { fprintf(RcFile," GROUPBOX \"\" %s, %d, %d, %d, %d", UserLabel, Tree[i].ob_x + xParent, Tree[i].ob_y + yParent, Tree[i].ob_width, Tree[i].ob_height); /* If we have started a radio button group */ if (RadioBtnIdx != SavedRBtnIdx) { /* then "insert" any child group at a higher id */ TmpRBtnIdx = RadioBtnIdx; RadioBtnIdx += MAX_RBTN_BOX; } else TmpRBtnIdx = 0; fprintf(RcFile, AddGroupStop ? ", WS_GROUP\n" : "\n"); if (AddGroupStop) { AddGroupStop = 0; FirstRButton = 1; } PrChildren(Tree, TreeIndex, i, xParent + Tree[i].ob_x, yParent + Tree[i].ob_y); if (TmpRBtnIdx) RadioBtnIdx = TmpRBtnIdx; } break; case G_BUTTON: fprintf(RcFile, " %s \"%s\" %s, %d, %d, %d, %d", Tree[i].ob_flags & RBUTTON ? (Label->MenuFlag = RadioBtnIdx++, "RADIOBUTTON") : (Tree[i].ob_flags & TOUCHEXIT ? (Tree[i].ob_flags & DEFAULT ? "DEFPUSHBUTTON" : "PUSHBUTTON") : "CHECKBOX"), Tree[i].ob_spec, UserLabel, Tree[i].ob_x + xParent, Tree[i].ob_y + yParent, Tree[i].ob_width, Tree[i].ob_height); if (Tree[i].ob_flags & RBUTTON) { if (FirstRButton) { fprintf(RcFile, ", WS_TABSTOP | WS_GROUP\n"); FirstRButton = 0; } else fprintf(RcFile, "\n"); AddGroupStop = 1; } else { fprintf(RcFile, ", WS_TABSTOP | WS_GROUP\n"); AddGroupStop = 0; } break; case G_STRING: case G_TITLE: fprintf(RcFile," LTEXT \"%s\" %s, %d, %d, %d, %d", Tree[i].ob_spec, UserLabel, Tree[i].ob_x + xParent, Tree[i].ob_y + yParent, Tree[i].ob_width, Tree[i].ob_height); fprintf(RcFile, AddGroupStop ? ", WS_GROUP\n" : "\n"); if (AddGroupStop) { AddGroupStop = 0; FirstRButton = 1; } break; case G_FTEXT: case G_FBOXTEXT: case G_BOXTEXT: case G_TEXT: Ted = (TEDINFO *) Tree[i].ob_spec; if (Tree[i].ob_flags & EDITABLE) fprintf(RcFile," %s %s, %d, %d, %d, %d", "EDITTEXT", UserLabel, Tree[i].ob_x + xParent, Tree[i].ob_y + yParent, Tree[i].ob_width, Tree[i].ob_height); else fprintf(RcFile," %s \"%s\" %s, %d, %d, %d, %d", "LTEXT", Ted->te_ptext, UserLabel, Tree[i].ob_x + xParent, Tree[i].ob_y + yParent, Tree[i].ob_width, Tree[i].ob_height); fprintf(RcFile, AddGroupStop ? ", WS_GROUP\n" : "\n"); if (AddGroupStop) { AddGroupStop = 0; FirstRButton = 1; } break; case G_BOXCHAR: break; } i = Tree[i].ob_next; } } PrMenu(Tree, TreeIndex) register OBJECT *Tree; int TreeIndex; { int TitleIndex; int EntryTrace; int EntryBox; int EntryQuit; int ColumnOne; struct DefFileEntry *Label; struct DefLabel *TitleLabel; char UserLabel[10]; TitleIndex = Tree[0].ob_head; EntryQuit = Tree[TitleIndex].ob_next; TitleIndex = Tree[TitleIndex].ob_head; TitleIndex = Tree[TitleIndex].ob_head; ColumnOne = 0; for (EntryBox = Tree[EntryQuit].ob_head; EntryBox != EntryQuit; (EntryBox = Tree[EntryBox].ob_next), (TitleIndex = Tree[TitleIndex].ob_next), (ColumnOne += 1)) /* go through the menu titles */ { if (!ColumnOne) { continue; } TitleLabel = (struct DefLabel *)FindObjLabel(LabelArray, NumLabels, TreeIndex, TitleIndex); if (TitleLabel) TitleLabel->MenuFlag = ColumnOne - 1; fprintf(RcFile, " POPUP \"%s\"\n {\n", Tree[TitleIndex].ob_spec); for (EntryTrace = Tree[EntryBox].ob_head; EntryTrace != EntryBox; EntryTrace = Tree[EntryTrace].ob_next) { bzero(UserLabel, sizeof(UserLabel)); Label = FindObjLabel(LabelArray, NumLabels, TreeIndex, EntryTrace); if (Label) { strncpy(UserLabel, Label->Label, sizeof(Label->Label)); UserLabel[sizeof(Label->Label)] = 0; } else strcpy(UserLabel, "-1"); fprintf(RcFile," MENUITEM \"%s\", %s%s\n", Tree[EntryTrace].ob_spec, UserLabel, Tree[EntryTrace].ob_state & DISABLED ? " GRAYED" : ""); } fprintf(RcFile," }\n"); } } ProcessObjTree(Tree, TreeIndex) OBJECT *Tree; int TreeIndex; { struct DefFileEntry *ObjectLabel; char UserLabel[10]; AddGroupStop = 0; ObjectLabel = FindTreeLabel(LabelArray, NumLabels, TreeIndex); bzero(UserLabel, sizeof(UserLabel)); if (ObjectLabel) { strncpy(UserLabel, ObjectLabel->Label, sizeof(ObjectLabel->Label)); UserLabel[sizeof(ObjectLabel->Label)] = 0; } else sprintf(UserLabel, "TREE%d", TreeIndex); if (ObjectLabel && ObjectLabel->Flag == 2) { fprintf(RcFile,"%s MENU\n", UserLabel); fprintf(RcFile," {\n"); PrMenu(Tree, TreeIndex, 0); fprintf(RcFile," }\n\n"); } else { fprintf(RcFile,"%s DIALOG 10 10 %d %d\n", UserLabel, Tree[0].ob_width, Tree[0].ob_height); fprintf(RcFile," STYLE WS_POPUP | WS_DLGFRAME\n"); fprintf(RcFile," {\n"); PrChildren(Tree, TreeIndex, 0, Tree[0].ob_x, Tree[0].ob_y); fprintf(RcFile, " }\n\n"); } }