Skip to content

Latest commit

 

History

History
346 lines (305 loc) · 12.6 KB

POXFileFormat.md

File metadata and controls

346 lines (305 loc) · 12.6 KB

POX (Proprietary Object eXtension) file format

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.

Ini data

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