home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Vectronix 2
/
VECTRONIX2.iso
/
FILES_07
/
PURE_P_2.LZH
/
PURE_P_2.MSA
/
RESOURCE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-06-12
|
11KB
|
296 lines
{ ------------------------------------------------------------ }
{ UNIT RESOURCES }
{ (c) 1992 Pure Software GmbH }
{ }
{ this unit enables the usage of linked-in GEM resource files. }
{ therefore the .RSC-file must be converted into an object }
{ file using BINOBJ. }
{ }
{ }
{ 1. Execute BINOBJ to create an object file, i.e. }
{ BINOBJ myrsc.rcs myrsc MyResource }
{ }
{ 2. Include the object file into the primary file using the }
{ $L-directive. }
{ }
{ 3. Declare the entry point for the resource file which must }
{ be the same identifier used at 1., i.e. }
{ procedure MyResource; external; (*$L myrsc *) }
{ }
{ 4. Initialize the linked-in resource file: }
{ resourcePool := InitResourcePool( @MyResource ); }
{ }
{ 5. now the variable resourcePool can be used to inquire the }
{ start address of an AESTree: }
{ menuTree := GetResource( resourcePool, MYMENU ); }
{ menu_bar( menuTree, 1 ); }
{ }
{ 6. before program termination you must call FreeResourcePool }
{ FreeResourcePool( resourcePool ); }
{ ------------------------------------------------------------ }
unit Resources;
interface
uses Gem;
type
TResource = AESTreePtr;
TResourcePoolPtr = ^TResourcePool;
TResourcePool = Pointer;
function InitResourcePool( unfixedResource : Pointer ) : TResourcePoolPtr;
procedure FreeResourcePool( pool : TResourcePoolPtr );
function GetResource( pool : TResourcePoolPtr; poolIndex : Word ) : TResource;
{ ============================================================ }
implementation
{$X+}
{ ------------------------------------------------------------ }
{ these are the maximum numbers of the named data structures }
{ a resource file can contain. }
{ ------------------------------------------------------------ }
const
MaxAESObjects = 2730;
MaxTedinfos = 2340;
MaxIconBlocks = 1820;
MaxBitBlocks = 4681;
{ ------------------------------------------------------------ }
{ the following record describes the header of a resource }
{ files. for further information see the GEM literature. }
{ ------------------------------------------------------------ }
type
ResourceHeaderTypePtr = ^ResourceHeaderType;
ResourceHeaderType = record
rsh_vrsn : Word;
rsh_object : Word;
rsh_tedinfo : Word;
rsh_iconblk : Word;
rsh_bitblk : Word;
rsh_frstr : Word;
rsh_string : Word;
rsh_imdata : Word;
rsh_frimg : Word;
rsh_trindex : Word;
rsh_nobs : Word;
rsh_ntree : Word;
rsh_nted : Word;
rsh_nib : Word;
rsh_nbb : Word;
rsh_nstring : Word;
rsh_nimages : Word;
rsh_rssize : Word;
end;
{ ------------------------------------------------------------ }
{ this variant record allows convenient accessing the resource }
{ file bytewise and also the resource header. }
{ ------------------------------------------------------------ }
ResourceFileTypePtr = ^ResourceFileType;
ResourceFileType = record
case Integer of
1: ( resourceHeader : ResourceHeaderType );
2: ( resourceData : Array[0..65535] of Byte );
end;
{ ------------------------------------------------------------ }
{ some data structures to deal with the different components }
{ of a resource file. }
{ ------------------------------------------------------------ }
TedinfoArrayPtr = ^TedinfoArray;
TedinfoArray = Array[0..MaxTedinfos] of TEDINFO;
IconBlockArrayPtr = ^IconBlockArray;
IconBlockArray = Array[0..MaxIconBlocks] of ICONBLK;
BitBlockArrayPtr = ^BitBlockArray;
BitBlockArray = Array[0..MaxBitBlocks] of BITBLK;
AESTreePtrArrayPtr = ^AESTreePtrArray;
AESTreePtrArray = Array[0..MaxAESObjects] of AESTreePtr;
{ ------------------------------------------------------------ }
{ FIXRSC means that the relative addresses of the components }
{ of the resource file should be fixed to absolute addresses. }
{ UNFIXRSC is the counteroperation. }
{ ------------------------------------------------------------ }
FixMode = ( FIXRSC, UNFIXRSC );
{ ------------------------------------------------------------ }
{ the gem function rsrc_obfix transforms relative coordinates }
{ to absolute ones. this procedure works the the other way }
{ round. }
{ the low byte of a relative coordinate contains a character- }
{ distance and the high byte a remaining pixel distance. }
{ ------------------------------------------------------------ }
procedure AbsToRelCoords( var coord : Integer; defCharSize : Integer );
var
px, ch : Integer;
begin
ch := coord div defCharSize;
px := coord mod defCharSize;
coord := ( px shl 8 ) + ch;
end;
{ ------------------------------------------------------------ }
{ since there seem to be some problems using rsrc_obfix we }
{ will do it ourselves. }
{ ------------------------------------------------------------ }
procedure RelToAbsCoords( var coord : Integer; defCharSize : Integer );
var
px, ch : Integer;
begin
ch := ( coord and $00ff ) * defCharSize;
px := coord shr 8;
coord := ch + px;
end;
{ ------------------------------------------------------------ }
{ the procedure FixResourcePool handles, depending on the }
{ parameter mode, the fixing respectively the un-fixing of the }
{ relative addresses of a resource file by adding or }
{ substracting the start address of the resource file. }
{ ------------------------------------------------------------ }
procedure FixResourcePool( unfixedResource : Pointer; mode : FixMode );
var
resourceFile : ResourceFileTypePtr;
resourceHeader : ResourceHeaderTypePtr;
tree : AESTreePtr;
treePool : AESTreePtrArrayPtr;
tedinfo : TedinfoArrayPtr;
iconblk : IconBlockArrayPtr;
bitblk : BitBlockArrayPtr;
obj, objCnt, objType : Integer;
defWidth, defHeight, dummy : Integer;
offset : LongInt;
begin
offset := LongInt( unfixedResource );
if mode = UNFIXRSC then
offset := -offset;
resourceFile := unfixedResource;
resourceHeader := @resourceFile^.resourceHeader;
graf_handle( defWidth, defHeight, dummy, dummy );
tree := @resourceFile^.resourceData[resourceHeader^.rsh_object];
for obj := 0 to resourceHeader^.rsh_nobs - 1 do
begin
if mode = FIXRSC then
begin
RelToAbsCoords( tree^[obj].ob_x, defWidth );
RelToAbsCoords( tree^[obj].ob_y, defHeight );
RelToAbsCoords( tree^[obj].ob_width, defWidth );
RelToAbsCoords( tree^[obj].ob_height, defHeight );
end
else
begin
AbsToRelCoords( tree^[obj].ob_x, defWidth );
AbsToRelCoords( tree^[obj].ob_y, defHeight );
AbsToRelCoords( tree^[obj].ob_width, defWidth );
AbsToRelCoords( tree^[obj].ob_height, defHeight );
end;
objType := tree^[obj].ob_type;
if ( objType = G_TEXT ) or ( objType = G_BOXTEXT )
or ( objType = G_FTEXT ) or ( objType = G_FBOXTEXT )
or ( objType = G_BUTTON ) or ( objType = G_STRING )
or ( objType = G_TITLE ) or ( objType = G_ICON )
or ( objType = G_IMAGE ) then
begin
Inc( tree^[obj].ob_spec.index, offset );
end;
end;
tedinfo := @resourceFile^.resourceData[resourceHeader^.rsh_tedinfo];
for obj := 0 to resourceHeader^.rsh_nted - 1 do
begin
Inc( LongInt( tedinfo^[obj].te_ptext ), offset );
Inc( LongInt( tedinfo^[obj].te_ptmplt ), offset );
Inc( LongInt( tedinfo^[obj].te_pvalid ), offset );
end;
iconblk := @resourceFile^.resourceData[resourceHeader^.rsh_iconblk];
for obj := 0 to resourceHeader^.rsh_nib - 1 do
begin
Inc( LongInt( iconblk^[obj].ib_pmask ), offset );
Inc( LongInt( iconblk^[obj].ib_pdata ), offset );
Inc( LongInt( iconblk^[obj].ib_ptext ), offset );
end;
bitblk := @resourceFile^.resourceData[resourceHeader^.rsh_bitblk];
for obj := 0 to resourceHeader^.rsh_nbb - 1 do
Inc( LongInt( bitblk^[obj].bi_pdata ), offset );
treePool := @resourceFile^.resourceData[resourceHeader^.rsh_trindex];
for obj := 0 to resourceHeader^.rsh_ntree - 1 do
Inc( LongInt( treePool^[obj] ), offset );
end;
{ ------------------------------------------------------------ }
{ this procedure start the un-fixing process. }
{ ------------------------------------------------------------ }
procedure FreeResourcePool( pool : TResourcePoolPtr );
begin
FixResourcePool( pool, UNFIXRSC );
end;
{ ------------------------------------------------------------ }
{ this procedure initializes the resource file and the GEM! }
{ ------------------------------------------------------------ }
function InitResourcePool( unfixedResource : Pointer ) : TResourcePoolPtr;
var
resourceFile : ResourceFileTypePtr;
resourceHeader : ResourceHeaderTypePtr;
treePool : AESTreePtrArrayPtr;
begin
FixResourcePool( unfixedResource, FIXRSC );
resourceFile := unfixedResource;
resourceHeader := @resourceFile^.resourceHeader;
treePool := @resourceFile^.resourceData[resourceHeader^.rsh_trindex];
GEM_pb.global[5] := Word( LongInt( treePool ) shr 16 );
GEM_pb.global[6] := Word( treePool );
InitResourcePool := unfixedResource;
end;
{ ------------------------------------------------------------ }
{ this function returns the address of a specific AESTree of }
{ the resource file. }
{ ------------------------------------------------------------ }
function GetResource( pool : TResourcePoolPtr; poolIndex : Word ) : TResource;
var
resourceFile : ResourceFileTypePtr;
resourceHeader : ResourceHeaderTypePtr;
treePool : AESTreePtrArrayPtr;
begin
resourceFile := ResourceFileTypePtr( pool );
resourceHeader := @resourceFile^.resourceHeader;
treePool := @resourceFile^.resourceData[resourceHeader^.rsh_trindex];
GetResource := treePool^[poolIndex];
end;
end.
{ ============================================================ }