Offset | Bytes | Description |
---|---|---|
0 | 4 | POXA |
4 | 2 | Object type |
ST : Static Resource |
||
CC : Non-Layered Character Resource |
||
LC : Layered Character Resource |
||
DS : Door Resource |
||
TT : Tile Resource |
||
PR : Projectile Resource |
||
SC : Cast Resource |
||
LL : (Linked) Layer Resource |
||
II : Inventory Resource |
||
SP : Resource |
||
6 | 2 | \r\n - filler |
8 | 4 | Size in bytes of Ini Data Block - iniLength |
12 | iniLength | Ini file content - ansi encoded |
12+iniLength | 2 | BB - Begin of RLE bitmap data stream (TRLESprite) marker |
... RLE bitmap data stream
Offset | Bytes | Description |
---|---|---|
0 | 4 | Picture Count - picCnt |
4 | 4 | RLE data size - rleSize |
8 | picCnt * RLEHDR record size | RLEHDR records - with pointer to RLE data offset |
9+(picCnt * RLEHDR record size) | rleSize |
RLE data - run length encoded image data |
Pascal pseudo code to read and decode the RLE data into bitmap/pixel data:
type
PRLEHDR = ^RLEHDR;
RLEHDR = record
SrcX : integer;
SrcY : integer;
Wdh : DWORD;
Hgh : DWORD;
AdjX : integer;
AdjY : integer;
PixFmt : DWORD;
DataPtr : PChar;
end;
var
Size, BuffSize, i : DWORD;
lpRLE, RelocOffset : PChar;
p : PRLEHDR;
Stream.Read( PicCnt, SizeOf( PicCnt ) );
Stream.Read( BuffSize, SizeOf( BuffSize ) );
Size := PicCnt * SizeOf( RLEHDR );
GetMem( lpSpr, Size );
Stream.Read( lpSpr^, Size );
GetMem( lpRLE, BuffSize );
Stream.Read( lpRLE^, BuffSize );
RelocOffset := PChar( lpRLE - lpSpr.DataPtr );
p := lpSpr;
for i := 1 to PicCnt do
begin
p.DataPtr := PChar( p.DataPtr + DWORD( RelocOffset ) );
DecodeRLE(p); // previously handled by digifxConvertRLE( dfx_hnd, p ) - which blocks any further progress
Inc( p );
end;
procedure DecodeRLE(rle: PRLEHDR);
begin
x := 0;
y := 0;
fin := TBytesStream.Create();
fin.Write(rle.DataPtr^, BuffSize);
fin.Position := 0;
try
while true do
begin
fin.Read(&c, 1);
case c of
1 : begin // colour/pixel data
fin.Read(&i, 4);
while i > 0 do
begin
fin.Read(&colour, 2);
SetPixel(X+rle.AdjX, Y+rle.AdjY, colour); // fill pixelmap/bits
inc(x);
dec(i);
end;
end;
2 : begin // add x offset
fin.Read(&i, 4);
i := i div 2;
inc(x, i);
end;
3 : inc(y); // new line, carriage return
0 : break;
end;
end;
finally
fin.Free;
end;
end;
the above code is based on findings by the_Bug (Jun 20th 2011) - on the german forums.
Legend
1TResource.LoadData
2TResource.LoadAction
3TCharacterResource.LoadData
4TProjectileResource.LoadData
5TDoorResource.LoadData
6TDoorResource.Define - might be code smell here!!!
7TStaticResource.Define
8TStaticResource.LoadData (TTileResource)
9LoadMap (TTileResource.LoadData)
10TLayerResource.LoadData
11TInventoryResource.LoadData
12TLinkLayered
13Not used/read
14Used for BMP import/export
[Header]
Property | Values | Description | Default | Use |
---|---|---|---|---|
ImageWidth | int | set FrameWidth | 96, 08 | 1,11 |
ImageHeight | int | set FrameHeight | 86, 08 | 1,11 |
Blend | add, [sub, subtract], alpha | set SpecialEffect (seAdd, seSubtract, seTranslucent, seNone) | 1 | |
BlendAmount | int | set Alpha | 100 | 1 |
UseLighting | none, vert, <else> | set UseLighting and Vertical | 1 | |
Highlightable | yes, <else> | set Highlightable : Enables a resource to be "highlighted" | 1 | |
Shadow | [no, none], <else>, simple | set DrawShadow and ComplexShadow | 1 | |
ShadowColor | int | set ShadowColor | 0 | 1 |
CollisionRadius | int | set Radius | 16 | 1 |
FrameMultiplier | int | set FrameMultiplier | 1 | 1 |
CollisionOffset | int | set CenterX | FrameWidth div 2 | 1 |
CollisionHeight | int | set CenterY | FrameHeight-10 | 1 |
Speed | string | set Speed (and RunSpeed) | '5.0' | 1 |
Actions | string | read list of "actions" whos inidata needs loaded and their TScripts are created | 1 | |
UseCastAnimation | 'false',<else> | set UseCastAnimation | 3 | |
GameClassType | 'multiimage' | set local var MultiImage (also true when FrameCount>1) - might be code smell here!!! | 6,7 | |
DepthAnchors | '','XX',<else> | call LoadArray( S, DepthAnchors ) | 6,7 | |
LightPoints | '','XX',<else> | call LoadArray( S, LightPoints ) | 6,7 | |
XRayable | 'no','',<else> | if : calculate Slope for Map.DefineItem | 6,7 | |
CollisionMask | '','XX',<else> | call LoadArray( S, CollisionMask ) | 6,7 | |
LineOfSightMask | '','XX',<else> | call LoadArray( S, LineOfSightMask ) | 6,7 | |
GameImageFrame | int | set ItemFrame | 191 | 10 |
LinkedLayerFile | string | set LinkedResource | 10 | |
LayeredFramesToBack | string | set BackLayer array (0..383) | 10 | |
FileName | string | 13 | ||
GameClass | string | 13 | ||
TransparentColor | int | 14 | ||
ImagePacking | bool | 13 | ||
EditorImage | int | 13 | ||
TileType | string | 13 | ||
Presentation | 13 | |||
ValidLayers | string | 12,13 | ||
LayeredParts | string | 12,13 |
MultiImage sections:
[CollisionMasks]7
Property Values Description Default Use Frame<ImageIndex + 1> '','XX',<else> call LoadArray( S, CollisionMasks ) 7 [LineOfSightMasks]7
Property Values Description Default Use Frame<ImageIndex + 1> '','XX',<else> call LoadArray( S, >LineOfSightMasks ) 7 [DepthAnchors]6, 7
Property Values Description Default Use Frame<ImageIndex + 1> '','XX',<else> call LoadArray( S, DepthAnchors ) 6, 7 [LightPoints]6, 7
Property Values Description Default Use Frame<ImageIndex + 1> '','XX',<else> call LoadArray( S, LightPoints ) 6, 7 [XRayable]6, 7
Property Values Description Default Use Frame<ImageIndex + 1> 'no','',<else> if <else>: calculate Slope for Map.DefineItem - !!Only last frame is used!! 6, 7
[Action<X>]2
Property | Values | Description | Default | Use |
---|---|---|---|---|
FrameMultiplier | int | set Multiplier | FrameMultiplier | 2 |
Frames | string | if <>'' load script with list of frames for <X> with Multiplier - TScript is created with Multiplier, array of frames and type/tag, and add these to the TAniResource.Script stgringlist with either TScript objects. | ||
SSFrames | string | if <>'' load script with list of frames* for <X>SS with Multiplier | 2 | |
SEFrames | string | if <>'' load script with list of frames* for <X>SE with Multiplier | 2 | |
EEFrames | string | if <>'' load script with list of frames* for <X>EE with Multiplier | 2 | |
NEFrames | string | if <>'' load script with list of frame* for <X>NE with Multiplier | 2 | |
NNFrames | string | if <>'' load script with list of frames* for <X>NN with Multiplier | 2 | |
NWFrames | string | if <>'' load script with list of frames* for <X>NW with Multiplier | 2 | |
WWFrames | string | if <>'' load script with list of frames* for <X>WW with Multiplier | 2 | |
SWFrames | string | if <>'' load script with list of frames* for <X>SW with Multiplier | 2 |
*list of frames is a comma seperated list of number with a end marker/script tag. - 'loop', 'random', 'die', <'end',''>
[Action Walk]1
Property | Values | Description | Default | Use |
---|---|---|---|---|
MovementPerFrame | string | set Speed - if <>'' | 1 |
[Action Run]1
Property | Values | Description | Default | Use |
---|---|---|---|---|
MovementPerFrame | string | set RunSpeed - if <>'' | 1 |
[Action Death]1
Property | Values | Description | Default | Use |
---|---|---|---|---|
MovementPerFrame | string | set DeathSlide (false = '-1' else true) | 1 |
[Action Attack1]3
Property | Values | Description | Default | Use |
---|---|---|---|---|
TriggerFrame | int | set FContactFrame | 1 | 3 |
[Action BowAttack]3
Property | Values | Description | Default | Use |
---|---|---|---|---|
TriggerFrame | int | set FReleaseFrame | 1 | 3 |
[Action Cast]3
Property | Values | Description | Default | Use |
---|---|---|---|---|
TriggerFrame | int | set FCastFrame | 1 | 3 |
[Action Explode]4
Property | Values | Description | Default | Use |
---|---|---|---|---|
TriggerFrame | int | set FContactFrame | 1 | 4 |
[Layers]3
Property | Values | Description | Default | Use |
---|---|---|---|---|
leg1 | string | set Equipment[ slLeg1 ] | '' | 3 |
boot | string | set Equipment[ slBoot ] | '' | 3 |
leg2 | string | set Equipment[ slLeg2 ] | '' | 3 |
chest1 | string | set Equipment[ slChest1 ] | '' | 3 |
chest2 | string | set Equipment[ slChest2 ] | '' | 3 |
arm | string | set Equipment[ slArm ] | '' | 3 |
belt | string | set Equipment[ slBelt ] | '' | 3 |
chest3 | string | set Equipment[ slChest3 ] | '' | 3 |
gauntlet | string | set Equipment[ slGauntlet ] | '' | 3 |
outer | string | set Equipment[ slOuter ] | '' | 3 |
helmet | string | set Equipment[ slHelmet ] | '' | 3 |
weapon | string | set Equipment[ slWeapon ] | '' | 3 |
shield | string | set Equipment[ slShield ] | '' | 3 |
tabar | string | set Equipment[ sltabar ] | '' | 3 |
misc1 | string | set Equipment[ slMisc1 ] | '' | 3 |
misc2 | string | set Equipment[ slMisc2 ] | '' | 3 |
misc3 | string | set Equipment[ slMisc3 ] | '' | 3 |
naked | string | set NakedResource, UseDefaultPants and Female ('humanmalelayers\basehumanmale.gif', 'humanfemale2layers\basehumanfemale.gif', 'elfmalelayers\baseelf.gif') | '' | 3 |
head | string | set HeadResource | '' | 3 |
*set FAttackVariations based on number of [Action Attack<N>] sections3
[Properties]3
Property | Values | Description | Default | Use |
---|---|---|---|---|
% - read section into Defaults strings | ||||
AIMode=IdleAI | ||||
CombatAI=BasicFight | ||||
IdleAI=Meander | ||||
PartyAI=Companion | ||||
AllowTalk=True | ||||
BaseCourage=5 | ||||
Combative=False | ||||
Distance=175 | ||||
HealFirst=True | ||||
IdleDuty=Menader | ||||
LeashLength=50 | ||||
MainStat=Strength | ||||
Moveable=True | ||||
TakeOrders=True | ||||
TimeToRun=75 | ||||
UndeadType=Skeleton | ||||
WolfType=Wolf | ||||
Charm=10 | ||||
Combat=5 | ||||
Constitution=7 | ||||
Coordination=7 | ||||
HealingRate=10 | ||||
Hearing=40 | ||||
HitPoints=10 | ||||
Mana=10 | ||||
Movement=10 | ||||
Mysticism=5 | ||||
Perception=10 | ||||
Smell=20 | ||||
Stealth=5 | ||||
Strength=7 | ||||
Recovery=10 | ||||
RechargeRate=10 | ||||
Restriction=0 | ||||
Vision=400 | ||||
BuyingDiscount=0.75 | ||||
IsMerchant=False | ||||
MoneyAmount=0 | ||||
SellingMarkup=1.25 | ||||
CharacterName=#Charactername.Scout# |
[ImageList]9
Property | Values | Description | Default | Use |
---|---|---|---|---|
Center | string | set DVariations[ i, ord( dqCenter ) ] := LoadIndexes( S ) | 9 | |
EECornerIn | string | set DVariations[ i, ord( dqIE ) ] := LoadIndexes( S ) | 9 | |
EECornerOut | string | set DVariations[ i, ord( dqOE ) ] := LoadIndexes( S ) | 9 | |
NEEdge | string | set DVariations[ i, ord( dqNE ) ] := LoadIndexes( S ) | 9 | |
NNCornerIn | string | set DVariations[ i, ord( dqIN ) ] := LoadIndexes( S ) | 9 | |
NNCornerOut | string | set DVariations[ i, ord( dqON ) ] := LoadIndexes( S ) | 9 | |
NWEdge | string | set DVariations[ i, ord( dqNW ) ] := LoadIndexes( S ) | 9 | |
WWCornerIn | string | set DVariations[ i, ord( dqIW ) ] := LoadIndexes( S ) | 9 | |
WWCornerOut | string | set DVariations[ i, ord( dqOW ) ] := LoadIndexes( S ) | 9 | |
SWEdge | string | set DVariations[ i, ord( dqSW ) ] := LoadIndexes( S ) | 9 | |
SSCornerIn | string | set DVariations[ i, ord( dqIS ) ] := LoadIndexes( S ) | 9 | |
SSCornerOut | string | set DVariations[ i, ord( dqOS ) ] := LoadIndexes( S ) | 9 | |
SEEdge | string | set DVariations[ i, ord( dqSE ) ] := LoadIndexes( S ) | 9 |