Copy Link
Add to Bookmark
Report
Ictari Issue 19
ICTARI USER GROUP ISSUE 19 February 1995
___ ______ ___ _________ _________ ___
\__\ \ __\ \ \__ \______ \ \ _____\ \__\
___ \ \ \ __\ _____\ \ \ \ ___
\ \ \ \ \ \ \ ____ \ \ \ \ \
\ \ \ \_____ \ \____ \ \__\ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ \ \
\__\ \_______\ \______\ \________\ \__\ \__\
* m a g a z i n e *
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
I C T A R I U S E R G R O U P
63 Woolsbridge Road, Ringwood, Hants, BH24 2LX Tel. 0425-474415
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
INDEX FOR ISSUE 19
==================
ASSEMBLY Various Falcon specific assembler routines.
Joystick reading routines.
'Thermometer' progress display code.
C GEM Tutorial by J White. Part 9.
Text packing using Huffman coding.
GFA AutoZest (GFA Interface Creation Utility)
GFA Programming Tricks and Tips.
STOS Mad Bomber game code.
Routines to draw Alert boxes and work out time/date.
PASCAL More small programs.
MISC Desktop .INF file information.
More information on GIF image format.
Current membership list.
In next months issue of ICTARI (this may change) :-
ASSEMBLY Using Calamus fonts in user programs.
Screen raster routines.
Making CPX accessory files.
C GEM Tutorial by J White. Part 10.
Questions and Answers file.
GFA Football game.
BASIC Disabling some menu items from Basic.
STOS STOS fix code for different TOS versions.
PASCAL Miscellaneous example programs.
MISC GIF/TIFF file information.
For future issues :-
Polyline drawing routines in machine code.
Bezier curve drawing routines.
Picture compression routine for IMG pictures.
HP DeskJet/LaserJet compression routines (Mode 2 TIFF).
Picture switching techniques.
Printer driver code for printing mono/colour images.
Sorting algorithms.
Using the BitBlit routines.
Code for using the File Selector.
Overscan techniques.
STOS sprites.
----------------------------------------------------------------------
EDITORIAL
=========
ARTICLE FORMATS
---------------
As we have had quite a few more members in recent months I thought I
would just mention again for their benefit that if you send in a text
file for publication it would help me if it was in Protext format
since that is the WP I use to compile these disks. If this is not
possible then a standard ASCII file will be quite OK.
CORRECTIONS
-----------
The GEM Macro information file (ICTARI 18) should be amended as shown
below.
The 'rsrc_obfix' function in the AES Resource Library section is
incorrect, the ENTRY parameter 'object' should read as follows : -
object = The number of the object to be converted
Thanks to John Logan for that. Also in the VDI Attribute Functions
section, the vsl_udsty heading should read :-
Set user defined line style.
but I'm sure you had already worked that one out.
TELEPHONE NUMBERS
-----------------
As you all know everyones telephone number changes on April 16th. Most
codes just have a 1 inserted after the initial 0 although some codes
will change completely. I will update the membership list next month
but if your number is one that changes radically, perhaps you could
let me know.
----------------------------------------------------------------------
CORRESPONDENCE
==============
To: Peter Hibbs
From: Keith Baines
Disabling menu entries when an accessory is opened.
I don't know how the HiSoft editors handle this; they have other
non-standard features like sub-menus as well. However, there is a
fairly straightforward way of checking whether a program's window
is on top, which is as follows:
- include a short (e.g. 10 millisecs) timer event in the
evnt_multi call.
- whenever this is called, use wind_get sub-function 10 to get
the handle of the current top window, compare this with the
program's own window handle(s) and adjust the menu as necessary.
I've included a short example program (MENUDEMO.BAS). This is
written in HiSoft Basic, but uses the AES window functions rather
than the built-in Basic window system, so should be easily
translated into other languages.
There are two extra tricks:
- we can ignore timer events which happen in the same evnt_multi
call as another event.
- the program uses a flag to keep track of whether it thinks its
window is on top; this cuts down the processing done for the
timer event.
*/ Thanks for the info, more on this subject next month. ICTARI /*
----------------------------------------------------------------------
To: Dick Teuber
From: Keith Baines
Embedded Resource Files
In assembler, the obvious way to embed a resource file in a program is
simply to include it as a binary (the INCBIN directive in Devpac 3).
The problem with this is that it needs some quite tricky code to
find and fix up all the pointers (which start off as offsets from
the start of the file). An easier way is to convert the RSC file
into assembler source code (mainly lots of DC.W statements) and let
the assembler deal with the addresses. This also produces shorter
code.
The only other fixup needed is to convert object co-ordinates from the
character/offset format in which they are stored in the RSC file into
screen positions for the current resolution. GEM provides the AES
function rsrc_obfix for this purpose; it has to be called once for
each object in the resource file.
I've included a simple example program to show how a conventional
program with an external resource file can be converted to use an
embedded resource.
demo1.s is the conventional program with an external resource
demo2.s includes its resource data as assembler source
I wrote a utility to convert RSC files into assembler a while ago
and have included a copy with its (HiSoft Basic) source.
*/ Thanks, we will be publishing this code later. ICTARI /*
----------------------------------------------------------------------
To: Dick Teuber
From: J I Logan
INCORPORATION OF *.RSC FILES INTO *.PRG FILES
OUTLINE
1. Insert the RSC file into the programme source file.
2. At run-time, convert pointers in the RSC file (which are offsets
relative to the beginning of the RSC file) to absolute memory
addresses.
3. At run-time, convert object heights and widths from the RSC
dimensions of character heights and widths to screen pixels.
DETAILS
INSERTING THE RSC FILE. You cannot simply import a large hex file into
a source file. It must be formatted in some way e.g. using dc.w
statements in assembler or defining it as an array. Examples:
label dc.w $0000,$0042,$0042,$0042, etc (assembler)
rsc[0]:=0; rsc[1]:=66; rsc[2]:=66; rsc[3]:=66; etc. (Modula-2)
Clearly it would be very laborious to construct these statements by
hand. Chris Greening has written CONVERT.PRG (available on Ictari
disk 18) which converts any file into dc.w statements. C programmers
will have to determine the format best suited to that language.
ADJUSTING THE POINTERS. I do not intend to explain the working of a
RSC file in detail but the RSC file has four consecutive components.
The first is the header consisting of the first 18 words (numbered 0
to 17). The second is the data area containing secondary and tertiary
structures (tedinfos, bltblks, strings, graphic data etc). The third
is the object list and the last is the tree list. The data area,
object list and tree list are not of fixed size.
Each file contains at least one tree and each tree contains at least
one primary structure called an object. There are thirteen different
types of object. Each object is 12 words long (numbered 0 to 11). The
type number is found in the low byte of word 3 (ie byte 7). In most
objects, longword 3 (ie words 6 and 7) points to a secondary structure
in the data area of the RSC file. This secondary structure may be self
contained or may itself contain pointers to tertiary structures. The
remaining objects are self contained and object words 6 and 7 do not
contain a pointer but rather information such as colour etc. The
object types are discussed below.
Object types 20 (g_box), 25 (g_ibox) and 27 (g_boxchar) are self
contained and do not point to any other structure. No changes are
required.
Object types 26 (g_button), 28 (g_string) and 32 (g_title) point to a
self contained secondary structure (their text string). The object
pointer must be converted to an absolute address.
Object types 21 (g_text), 22 (g_boxtext), 29 (g_ftext) and 30
(g_fboxtext) point to a tedinfo structure. The first three longwords
in the tedinfo structure point to tertiary structures (text, template
and validation strings). The object pointer and the three tedinfo
pointers must be converted to absolute addresses.
Object type 23 (g_image) points to a bitblk structure. The first
longword in the bitblk structure points to a tertiary structure (bit
image). The object pointer and the bitblk pointer must be converted to
absolute addresses.
Object type 31 (g_icon) points to an iconblk structure. The first
three longwords in the iconblk structure point to tertiary structures
(icon mask, icon data and text). The object pointer and the three
iconblk pointers must be converted to absolute addresses.
Object type 24 (g_progdef) points to an applblk structure. The two
longwords in the applblk structure point to tertiary structures
(programme code and parmblk). The parmblk has two longword pointers.
The object pointer, the two applblk pointers and presumably the two
parmblk pointers must be converted to absolute addresses.
Each of the above pointers contains an offset or displacement IN BYTES
from the beginning of the RSC file. It is a simple matter to determine
the absolute address of the beginning of the RSC file after it has
been loaded at run-time. The addition of the absolute address of the
beginning of the RSC file to the offset from the beginning of the RSC
file converts the pointers to absolute addresses. Because the absolute
address is only known at run-time, the programme must contain code to
adjust the pointers.
Since all the objects are grouped together, it is easy to start at the
beginning of the object list and process each object in turn until the
last object has been dealt with. I have listed below the outlines of a
suitable procedure (FixObject). NOTE the pointers in the header should
not be converted to absolute values.
How do we know where the object list starts and how many objects there
are? The header tells us. Word 1 of the RSC file header contains the
offset IN BYTES from the start of the RSC file to the start of the
object list. Word 10 of the RSC file header tells us the number of
objects in the list. The table gives the function of each header word
as far as I have been able to work them out.
word 0 uncertain
word 1 offset of start of object list IN BYTES
word 2 offset of start of tedinfo list IN BYTES
word 3 offset of start of iconblk list IN BYTES
word 4 offset of start of bitblk list IN BYTES
word 5 uncertain
word 6 uncertain
word 7 uncertain
word 8 uncertain
word 9 offset of start of tree list IN BYTES
word 10 number of objects
word 11 number of trees
word 12 number of tedinfos
word 13 number of iconblks
word 14 number of bitblks
word 15 uncertain
word 16 uncertain
word 17 size of RSC file IN BYTES
The tree list also needs some attention. It is simply a list of
longwords, one for each tree. Each longword points to the first object
in its respective tree. Each longword in the tree list must be
adjusted by adding the RSC_start_address to it. The offset of the
start of the tree list IN BYTES is in RSC header word 9 and the number
of trees is in RSC header word 11.
Compute!'s Technical Reference Guide volume 2 (AES) page 136, mentions
that when a non-incorporated RSC file is loaded using the rsc_load
call, the operating system adjusts the tree list pointers and then
stores the absolute address of the beginning of the tree list in the
ap_ptree field of the application's global data array. It would seem
sensible for us to do the same.
ADJUSTING OBJECT DIMENSIONS. The reason RSC file object dimensions are
given in character heights and widths is that the one RSC file can be
converted to work with different ST/TT resolutions at run-time. This
saves writing different versions of the RSC file for each screen
resolution.
Object sizes are converted by calling the operating system using
rsc_obfix. The call requires the programmer to pass both the address
of the tree (ie the absolute address of the first object in the tree)
and the number of the object. If we were to call rsc_obfix, tree by
tree and object by object, we run into a minor problem of knowing when
we get to the end of each tree. It is not possible to determine this
by direct inspection of the RSC header. The last_object in the tree
hierarchy should have bit 5 of word 4 set and it should also have its
first word (the ob_next field) set to 0. This last_object may not be
the last physical object in the tree object list. It would be possible
to determine the length of the tree in bytes and divide the size by 24
to get the number of objects in the tree.
Fortunately I think it is likely that rsc_obfix only uses the object
number to index forward into the object list from the tree start
address and does not concern itself with the actual object numbers. If
this is so then the whole object list can be treated as one tree. This
would allow us to process pointers and sizes in the same procedure and
simplifies our task.
PSEUDOCODE
Procedure FixObject;
RSC_start_address := absolute RSC start address (bytes);
Object_list_address := absolute object list start address (bytes);
Object_address := Object_list_address (bytes);
Number_of_objects := RSC file header word 10;
Object_size := 24 (bytes);
FOR N = 0 TO (Number_of_objects-1)
DO
Object_address := Object_address + (N * Object_size)
Object_byte_7 := value of byte at (Object_address + 7)
IF Object_byte_7 = 20 or 25 or 27 THEN
no action required;
END IF;
IF Object_byte_7 = 26 or 28 or 32 THEN
add RSC_start_address to object_longword_3;
END IF;
IF Object_byte_7 = 21 or 22 or 29 or 30 THEN
add RSC_start_address to object_longword_3;
use object_longword_3 to access tedinfo;
add RSC_start_address to tedinfo_longword_0;
add RSC_start_address to tedinfo_longword_1;
add RSC_start_address to tedinfo_longword_2;
END IF;
IF Object_byte_7 = 23 THEN
add RSC_start_address to object_longword_3;
use object_longword_3 to access bitblk;
add RSC_start_address to bitblk_longword_0;
END IF;
IF Object_byte_7 = 31 THEN
add RSC_start_address to object_longword_3;
use object_longword_3 to access iconblk;
add RSC_start_address to iconblk_longword_0;
add RSC_start_address to iconblk_longword_1;
add RSC_start_address to iconblk_longword_2;
END IF;
IF Object_byte_7 = 24 THEN
add RSC_start_address to object_longword_3;
use object_longword_3 to access applblk;
add RSC_start_address to applblk_longword_0;
add RSC_start_address to applblk_longword_1;
(may need to adjust the pointers in parmblk also);
END IF;
rsc_obfix (Object_list_address,N);
END DO;
END FixObject;
NOTE Object types 23 and 31 contain height and width data in their
secondary structures (bitblk and iconblk). If their appearance is
abnormal on the screen, try excluding them from rsc_obfix.
GENERAL COMMENT. I dabbled with this subject some years ago. I cannot
guarantee the accuracy of this contribution but I think it is more or
less right. Any comments or corrections would be welcome. If anyone
gets it to work they might like to send their code to Ictari for
publication.
----------------------------------------------------------------------
To: Dick Teuber
From: Iain McLeod
In Reply to Dick Teuber's question on how to incorporate a .RSC file
within a C file, Lattice C holds the answer.
It has a utility program which converts the .RSC file to the
equivalent structural information that it is referenced by in C code.
You simply pass the name of the .RSC file to the 'RSC Decompiler'
which does all this and also creates two functions:
rsrc_init() - Call this function at the start of your program which
calls fix_tree(), passing all your Form Dialogs each time.
fix_tree() - This simply then calls the function rsrc_obfix(),
passing all the items in the specified Form Dialog to fix its
coordinates to pixels.
So, as you can see, it is quite straightforward in that all you need
to do is write the resource in by hand (time consuming and you will
need a book for reference - I recommend Atari Compendium or the
Lattice C Manual Book 1) and have a function to go through *all* the
resource items and call rsrc_obfix() on them all, (you will of course
still need to #include the .H header file). Writing the resource by
hand isn't the most efficient way (!) so if you use the 'RSC
Decompiler' utility (I would expect it's copyrighted to HiSOFT) or
even if someone did their own Decompiler.
I would expect the above applies to .S assembly files also in that
simply using rsrc_obfix() and setting up the Form Dialogs in a dc.b/w
manner will achieve the same result.
I always use my .RSC files in this way (- you never know what folk
will want to do with your .RSC files, the Vandals!) and it makes for
less files in a final executable program.
----------------------------------------------------------------------
To: *.*
From: Adrian Lovatt
Plea - does anyone have a description of the CAD3D2 file format, I am
writing a program to convert CAD objects into a format usable by
POVRAY, but really need the file info. If anyone can help or has any
ideas please get in touch.
Has any HiSoft Basic programmer out there ever tried to put a Basic
sub-program into the VBI list ?.
----------------------------------------------------------------------
To: Jonathon White
From: Mark Baker
Your comments on evnt_multi() in the GEM tutorial are rather
misleading if not just wrong. Use of evnt_multi() does not freeze the
system until it returns. It only freezes your program, and allows
other programs to continue execution. In fact other programs can
_only_ run during evnt_multi() in co-operative multitasking systems
such as Geneva. So far from harming the multitasking, it is essential
for a well behaved program to spend as much time as possible in
evnt_multi() or another event library call.
Because they take the program out of the evnt_multi(), timer events
should be avoided if possible as they slow down everything. Obviously
if you have to have them do so, but don't use any unnecessarily. When
you should have timer events is on their own using an evnt_timer()
call in the middle of a large block of processing.
The real reason you can't access the menus when there is a dialogue
box on screen is that you do a wind_update() to turn them off before
you draw the dialogue. This is done deliberately to simplify the
dialogue code. evnt_multi() obviously doesn't turn off the menus as
that's what you normally use to detect menu events!
Don't see this as an attack on your otherwise excellent series, it's
just that I would hate to see anyone following your advice on timer
events.
----------------------------------------------------------------------
To: *.*
From: Tony Harris
i) I need the routines to play Quartet songs in assembly,
this is very urgent!
ii) Does anyone know how to do sine waves in assembler?
iii) This is a little embarassing, but what the hell is overscan
and have I got one in my 1Mb STE, if so, how do I use it,
and if not, why not?
*/ AutoSwitch Overscan (as I understand it) is a hardware device which
has to be fitted to the computer and effectively makes the screen
display larger. In the case of a monochrome monitor the screen area is
changed to about 672 pixels wide by 480 pixels high and so can display
more information on screen than a normal display. Unfortunately a lot
a of programs do not take advantage of the extra area so it is not
much use on these programs. I think Calamus does make use of the extra
area and I would guess that some of the modern WordProcessors and CAD
programs do, you would have to check before buying one. The hardware
is available from Compo Software Ltd in Huntingdon for about 50 and
there was a review published in Issue 6 of ST Applications magazine.
Whether it works on an STE I don't know but Compo should be able to
tell you.
Another system works purely in software and allows the programmer to
use the top, bottom and side borders to a certain extent and we will
be publishing some routines to do this from Diamond Software next
month, but don't ask me how it works because I still don't understand
it. If anyone wishes to add more on the subject, please send it in to
us. ICTARI /*
----------------------------------------------------------------------
To: ICTARI
From: Martyn Wells
I am writing a program which uses Videomaster format files i.e. VID,
FLM, VSQ but I am having trouble with the colours in the files as
these are written in the Amiga format xxxxrrrr/ggggbbbb. Is there a
quick way of converting them to the Degas format without using lookup
tables as the film files are quite large sometimes and I need to save
as much memory space as possible.
--------------------------- End of file ------------------------------