FB II Compiler







Disk I/O














Made with FB


Create custom resources

I wrote a nice program to read my GPS Navigator aboard my sailboat and display my position on self-made digital maps.
These maps are vectorized from scanned material and are stand-alone files and consist of sequencial coordinates for the coastline, name and position of lighthouses, etc.
I could be nice if these files become resources in my application and are menu-selected.
How can I do that? What kind of resource to use? Code resource, TEXT resource? How to make the resource? cut'n paste in ResEdit? From FB?
How to read the resource in my various arrays?

Michel Verheughe

It sounds like these files are in a custom format that doesn't correspond to any common file or resource format; if that's the case, I'd suggest that you make up some 4-character designation (like "DMAP" or something) and use that as the resource type (you can make up any resource type you like--you're not restricted to the "classic" types).

There are probably shareware programs that can convert a file's (data fork) contents into a resource--in any case, it's not hard to write an FB program to do the same. Basically, it would work like this:

1. Open the data file;
2. use the LOF function to get the file's size;
3. create a new handle of the appropriate size;
4. LOCK the handle;
5. Read the file's data into the handle (e.g.: READ FILE #1, [handle&], numBytes&)
6. Open a resource file;
7. Use ADDRESOURCE to add the handle as a resource (of your chosen type)

You _may_ find that your data is easily represented as a series of strings. In that case, consider storing it as a resource of type STR#. If you do that, then the internal format of the resource would be slightly different from the internal format of your data file, so you would NOT use the above 7 steps. There are functions built in to FB which make it easy to put strings into an STR# resource and extract them. The maximum number of strings you can have in an STR# resource is 32767.

But let's assume that you can't use an STR# resoure. When you _use_ a resource, typically you load the entire resource into memory at one time (there are ways to load a _part_ of a resource, but I've never done that, so I can't comment on it). Having read the data into memory, you'll have a handle for it: let's call that resHndl&. The expression [resHndl&] (with the brackets) then represents the address of the beginning of the resource data, and you can access the individual bytes of data by looking in addresses which are offset by the appropriate amount from [resHndl&]. For example, if you're interested in a certain long-integer value which is 20 bytes past the beginning of the data, you can get it as follows:

myLong& = PEEK LONG([resHndl&] + 20)

In a similar way, a short integer can be gotten via PEEK WORD, a single byte can be gotten via PEEK, and a string can be gotten via PSTR$.

To make sure the data block doesn't move around while you're working with it, call HLOCK. If it's a purgeable resource, and you suspect it may have been purged since you called GETRESOURCE, then call LOADRES to make sure it's in memory.

Some caveats about using resources:
I don't know what your data is like, but it sounds like it could be large. The sum of the resource sizes in your resource file cannot exceed 16 MB. Also, there is an absolute limit of about 2700 resources that you can have in the file, and that number could be limited further, depending on the file's contents.


I can't believe I have something to add to one of Rick's thorough explanations...

It sounds like your data is in record format, something like:

dim record mapRec
dim coastline%
dim 32 name$
dim position%
dim end record .mapRecSize

Assume that you are going to follow Rick's advice, then consider this change:
If you want to use the new resource that you have created, then ahead of time dim more space than you are going to read in record form:
e.g. dim map.mapRecSize(1000) '(or alternatively you could XREF a memory handle).
Then when you load your resfile, copy it to the address of the first element of the array, i.e. @map(1). This will allow you to read your data directly out of the array.

To keep track of file names, be sure to write the name of each file as the resource name when you create the original resources. Then you can later read the names using one of the GETRESINFO type routines and dump the names into a string array for your menus to access.

Hope this helps. It's been some time since I've used the Resource Manager.

Mark Goodes