home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
No Fragments Archive 10: Diskmags
/
nf_archive_10.iso
/
MAGS
/
ST_USER
/
1992
/
USERJN92.MSA
/
RTCCCH_RTCCCH.TXT
< prev
next >
Wrap
Text File
|
1992-03-01
|
13KB
|
290 lines
INSTRUCTIONS FOR
RESOURCE TO C CODE CONVERTER V1.2 (RTCCCH.PRG)
Machine: Atari ST/TT range
Resolution: ST-Low, ST-Med, ST-High, TT-Low, TT-Med, TT-High
Memory: 512K
Hello fellow ATARI ST programmers,
This utility program converts any standard ST resource file into a C
code file, which can be easily imported into your own C programs. It
effectively performs the error prone task of hard-coding your resource
files. Naturally, this program requires the use of a resource
construction set (RCS) and an implementation of the C language. It has
been specifically designed to work with the Lattice C V5 Development
System, produced by HiSoft.
I will assume, that you have some elementary knowledge of object trees
and resource files, but if you don't, there are a number of books on the
subject.
Why hard-code resources?
If you look at your collection of GEM software, the chances are that
most of them will make use of an external resource file which is stored
in the same directory. However, once in a while you'll come across a
program that uses menus and dialog boxes, but there isn't a resource
file to be found anywhere. In this case, the resources have been hard-
coded into the program. There are advantages to both methods and it
depends really on the preference of the programmer.
The classic argument for keeping resources external, is that you can
make limited changes to the resources without recompiling the source
code. Thus, if the program makes extensive use of a resource file, the
program can be translated into a different language, without having to
refer back to the source code. However, these changes are severely
limited, as the structure of the resource has to be preserved. No
objects may be added or deleted and only their contents, size and
location may be changed.
On the other hand, if the resources are included in the source file,
they become human readable, can easily be printed for a permanent record
and are far easier to document. Small changes can be made from the
editor, but is only recommended if you know what you are doing.
The RTCCCH program automatically assigns each structure occurrence a
unique identifier, so they can be directly accessed without the use of
indirection. For example, if you wished to access an input field in a
form, you can directly access the string in the appropriate occurrence
of the TEDINFO structure. No longer will you have to find the address
of the structure through the ob_spec field of the object. In my
opinion, this makes programming with resources much easier, especially
for beginning GEM programmers.
The third reason is that resources may now be optimized. For example,
a form contains two similar bit images, which are duplicated in the
object tree. Space could be saved if the only the first occurrence of
the bit image is kept and the pointer to the now 'missing' bit-image is
redirected to the first image.
The fourth reason, perhaps the most important reason where the C
language is concerned, resources can now be local to files and
functions. C is a structured language, in which a function's data is
local and hidden from other functions and modules, this concept can be
extended to resources as well. In a huge project, where hundreds of
functions are scattered across a dozen or so files, local resources are
far easier to manage than one large resource file. Local resources also
enable the creation of stand-alone C libraries that use resources.
If your program is to run in more than one resolution, you may have to
use more than one resource file. The resolution in which RTCCCH.PRG is
executed DOES affect the resulting code file. The program loads the
resource using the rsrc_load() function, which automatically makes
adjustments to the coordinates to conform to the current resolution.
So remember to run RTCCCH.PRG in the resolution in which the resource
is to be used.
There are basically two ways to deal with the resolution problem, one
is to have access to several version of the same resource, or to write a
piece of code which alters the object tree as required. What I
recommend, is that you create several versions of the resource file
using your RCS and then convert them all and then compare them. That is
what I have done when I wrote RTCCCH. Let experience is your tutor.
How to use RTCCCH.PRG
When running RTCCCH.PRG, you are presented with a dialog that handles
every function of the program. The Input File field should contain the
name for the resource file which is to be converted. The Output File
field should contain the name of the resultant C code file. The two
'Ask' buttons call up the file selector for the respective fields.
You may not always wish to convert the whole resource file, thus you
can specify a range of trees to convert. The first tree has an index of
zero, the second and index of 1 and so on. The default indexes of are
set to zero, so only the first object tree is converted.
When dealing with a huge object tree, it is quite difficult to
determine the index of a particular object (unless you want to refer to
the header file produced by the RCS), therefore RTCCCH.PRG gives you the
option of including the index number in front of every object in
comments.
You also have the option of producing external declarations only,
which is useful if the actual object tree is to be located in another
module.
The 'OK' button will perform the conversion and the 'Exit' button
quits the program.
Some care must be taken when this program is run. The input file
should be a standard resource file and the indexes of the object trees
to be converted must be a valid range, otherwise the program may produce
unpredictable results.
WARNING: The output file produced will OVERWRITE an existing file.
A C code object tree will consist of several occurrences of structures
followed by an array of objects. The objects in the array will be
linked to each other using indexes (short integers) and may be linked to
a structure using a label.
A label is generated as follows: The name of the type of the object
is followed by the tree index. Structures other than the object tree
will be followed by an underline symbol and the object index number.
This is to ensure that there are no duplicate labels, while still being
reasonably readable.
NOTE: If a object tree should use ProgDefs, a reference label is set
up as outlined before, but it is left up to the programmer to define.
Following is an example of how to effectively use this program.
We are going to write a program, that displays a dialog box with a bit
image of a smiling face, two strings 'Are you' and 'happy?' and a 'Yes'
and 'No' button, all within a border. Below is an approximation of how
it is going to look like.
-------------------
| ------ | (Diagram not to scale -
| | O O | | In reality the bit image
| | | Are You | will be much smaller)
| | | | | happy? |
| | -- | |
| ------ |
| |
| ----- ---- |
| | Yes | | No | |
| ----- ---- |
-------------------
The first step is to load a resource construction set and create this
dialog box and save it to disk, say under the name 'DIALOG1.RSC'.
Any other files the RCS may produce are unnecessary.
The next step is to load up RTCCCH. The resource name and C code
should be set to 'DIALOG1.RSC' and 'DIALOG1.C', respectively. Remember,
that you may use full path names with drive letters. Alternatively,
press the 'Ask' buttons to use the file selector.
Because there is only one object tree in the file, the indexes should
be left as they are.
Then simply press the 'OK' button. A message should come up to tell
you that the resource has been successfully converted and you are
returned to the dialog. Simply press the 'Exit' button to quit the
program.
The above instruction should produce a file that look something like
this:
short bi_pdata0_1[] =
{ 0x0000,0x03C0,0x0C30,0x1008,0x2004,0x2664,0x4662,0x4002,0x4002,0x4002,
0x2424,0x23C4,0x1008,0x0C30,0x03C0,0x0000
};
BITBLK bitblk1 =
{ bi_pdata1, 2, 16, 0, 0, 1
};
OBJECT object_tree0[] =
{ -1, 1, 5,G_BOX, 0x0000,0x0000,(void *)0x021181,16,16,152,96,
2,-1,-1,G_IMAGE, 0x0000,0x0000,(void *)&bitblk0_1,16,16,16,16,
3,-1,-1,G_STRING,0x0000,0x0000,(void *)"Are you",56,16,56,16,
4,-1,-1,G_STRING,0x0000,0x0000,(void *)"happy?",56,32,48,16,
5,-1,-1,G_BUTTON,0x0005,0x0000,(void *)" Yes ",16,64,56,16,
0,-1,-1,G_BUTTON,0x0025,0x0000,(void *)" No ",88,64,48,16
};
Once we give the object trees some sensible names, you are ready to
write the program to handle the object tree. The full program is below.
#include <aes.h>
short happy_image[] =
{ 0x0000,0x03C0,0x0C30,0x1008,0x2004,0x2664,0x4662,0x4002,0x4002,0x4002,
0x2424,0x23C4,0x1008,0x0C30,0x03C0,0x0000
};
BITBLK happy_block =
{ happy_image, 2, 16, 0, 0, 1
};
OBJECT ask_if_happy[] =
{ -1, 1, 5,G_BOX, 0x0000,0x0000,(void *)0x021181,16,16,152,96,
2,-1,-1,G_IMAGE, 0x0000,0x0000,(void *)&happy_block,16,16,16,16,
3,-1,-1,G_STRING,0x0000,0x0000,(void *)"Are you",56,16,56,16,
4,-1,-1,G_STRING,0x0000,0x0000,(void *)"happy?",56,32,48,16,
5,-1,-1,G_BUTTON,0x0005,0x0000,(void *)" Yes ",16,64,56,16,
0,-1,-1,G_BUTTON,0x0025,0x0000,(void *)" No ",88,64,48,16
};
int main(void)
{ short x, y, w, h;
/* initialize the application */
appl_init();
/* center the dialog box */
form_center(ask_if_happy, &x, &y, &w, &h);
/* reserve the necessary workspace */
form_dial(FMD_START, 0, 0, 0, 0, x, y, w, h);
form_dial(FMD_GROW, 0, 0, 0, 0, x, y, w, h);
/* draw the dialog box */
objc_draw(ask_if_happy, ROOT, MAX_DEPTH, x, y, w, h);
/* handle dialog box */
form_do(ask_if_happy, 0);
/* remove the dialog box and return the workspace */
form_dial(FMD_SHRINK, 0, 0, 0, 0, x, y, w, h);
form_dial(FMD_FINISH, 0, 0, 0, 0, x, y, w, h);
/* terminate the application */
appl_exit();
/* return to calling program */
return 0;
}
That's all there is to it. Why don't you try lifting the above
section out of this file, compile and run it.
Menus are handled much in the same fashion, but you use the menu_bar()
function to display the menu bar and use either evnt_mesag() or
evnt_multi() to use them. Below is a rough skeleton of what you are
expected to do.
#include <aes.h>
...
OBJECT menu[] = \
{ ... | This is the output of RTCCCH.PRG
... |
}; /
int main(void)
{ short message[8];
/* initialize the application */
appl_init();
/* install the menu */
menu_bar(menu, 1);
/* wait for a menu event */
do
{ evnt_mesag(message);
} while (message[0] != MN_SELECTED);
/* deinstall the menu */
menu_bar(menu, 0);
/* terminate the application */
appl_exit();
return 0;
}
If you have any problems with this program or have some ideas on how
to improve it, do not hesitate to contact me.
Arnd Hurlbrink
8 Mahonia Place
Duncraig WA 6023
West Australia
Watch out for an assembler version of this program sometime in the
future. Well, that's all from me for now. Happy programming!
Written 04/11/91
Updated 20/02/92
End Of File