| I never had any qualms about storing the data in the executable. After
all, what could possibly go wrong (click) go wrong (click) go wrong
(click) go wrong (click) go wrong (click) go wrong (click)...
I do this in Whack for the following reasons:
- It makes finding the data easier. It's always there when you
want it, right in your address space. No complicated user
instructions about where to put the data file where the program
can find it.
- It makes startup time faster, particulary for floppy users,
since I don't have to do anything special to READ the data.
- I HATE resource files. I like having the program all in one
place. It's so easy for a resource (or a set-up file) to be
inaccessible, and that tends to make the program crash or
otherwise not work.
- Not that for Whack, I'm assuming that each user will set
their preferred setup values once, when they receive the
program, and essentially never bother with it again. Therefore,
I'm not worried about anything going wrong. If a user has two
or three favorite SET-UP settings for different users, they can
rename a copy of WHACK.PRG for each one.
Here's how I do it:
1 - I use Mark Williams C. I can't say if this will work for any other.
2 - I declare the block of data as initialized and "readonly", as follows:
typedef struct setup *SETUP_ID;
readonly struct setup default_setup =
{
80, 24, /* Columns, Rows */
592, 768, /* Sixel window size (Width must be a multiple of 16) */
0, 1, /* Font, wrap */
WHITE, BLACK, /* drawing colors, delete key */
2, 4, /* DEL key mode, minimum slider width */
1, 1, /* flourish, titlebar */
2, 4, 1, 0x98, 0, 3,/* SSU, speed, flow, ucr, local, reset */
256, 256, /* Input buffer & output buffer sizes */
50, 1, /* Long and short times in ms */
48, 24, /* Max received, transmitted per iteration */
600, 400, 20, /* Cursor on, off, delay times */
32000L, /* Private arena */
2, /* Desktop fish count */
'w', 'h', 'a', 'c', 'k', '.', 'p', 'r', 'g', 0
};
3 - I make sure that this is the FIRST readonly data to be encountered
by the linker. It's at the beginnning of the first file specified to
the "ld" program.
4 - I use the following routine for either saving new default setup
values in the executable, or for restoring the saved default setup
values from the executable. Note that I don't have to restore them
unless they have changed and we want the original values back.
Normally, you just access the structure "default_setup" in the usual
way. The way this works is that it reads in the image header, which is
a fixed structure defined by GEM, and dereference the pointer to the
initialized data block. Fseek() to the data block, and do my I/O there.
#include <gemout.h> /* Contains struct gemohdr */
int setup_permanant( settings, writecontrol)
SETUP_ID settings; /* Settings to save */
int writecontrol; /* TRUE to write, FALSE to read */
{
struct gemohdr head; /* WHACK program header */
int hand; /* WHACK.PRG file handle */
long where; /* Fseek position in file */
hand = Fopen( settings->filepath, 2);
if( hand < 0)
{ /* Unable to open file */
char err[ 100];
sprintf( err, "[3][Failed to open Whack image file|%s][Grumble]",
settings->filepath);
form_alert( 1, err);
return( hand);
}
/*
Read file header
*/
Fread( hand, (long) sizeof( head), &head);
/*
Locate first element of readonly data psect, assume it is setup
*/
where = Fseek( (long) head.g_ssize[ GO_TEXT], hand, 1);
if( writecontrol) Fwrite( hand, (long) sizeof( *settings), settings);
else Fread( hand, (long) sizeof( *settings), settings);
Fclose( hand);
}
|