Daggerfall's BSA File Formats
	              by Dave Humphrey - dave@uesp.net
 		                 6 April 2002

This is a description of the format of the various .BSA files found in the
ARENA2 directory of Elder Scrolls:Daggerfall by Bethesda.  The information
here is not complete or 100% percent accurate, although the basic formats
appears to be well understood.  For more information, corrections, or 
comments, e-mail me at the above address.  Check out 

		http://www.uesp.net/dagger/ 

for the latest version of this document and other DF goodies.


  CONTRIBUTORS
================================
Significant contributors to these formats include:

     Michael [subproperty@hotmail.com] 
	- Dungeon Pre/Postrecords
	- Location types 
	- BLOCKS.BSA RDB format


  CONTENTS
================================
  General BSA Files
	General File Layout
	BSA Header
	BSA Records
	BSA Directory
	BSA 0x0100 Directory
	BSA 0x0200 Directory
  MAPS.BSA
	General File Layout
	Location Offset Section (MapPItem)
	Location Record Data (MapPItem)
		Location Records
		Dungeon Records
        Location PreRecords Sub-Format
        Location PostRecords Sub-Format
	Dungeon Offset Section (MapDItem)
	Dungeon Record Data (MapDItem)
	Location Table Section (MapTable)
	Location Name Section (MapNames)
	Map Directory
  ARCH3D.BSA
	General File Layout
	BSA Header
	3D Object Records
	3D Object Header
	Plane Data Record Section
  BLOCKS.BSA
	RMB General File Layout
        	RMB Fixed Length Data (FLD)
			RMB FLD Record Counts
			RMB FLD Header
			RMB FLD Section1
			RMB FLD Section2
			RMB Section1 Sizes
			RMB FLD Section3
			RMB FLD Section4
			RMB FLD Filenames
		RMB SubRecords
			RMB SubRecords1
			    	RMB SubRecord1 Header
			    	RMB SubRecord1 Section1
			    	RMB SubRecord1 Section2
			    	RMB SubRecord1 Section3
			    	RMB SubRecord1 Section4
			    	RMB SubRecord1 Section5
			RMB SubRecords2
			RMB SubRecords3
  Appendix A - REGION NUMBERS
  Appendix B - LOCATION TYPES
  Appendix C - BLOCK INDICES
  Appendix D - COORDINATE LIMITS
  Appendix E - UV TEXTURE COORDINATES


  GENERAL BSA FILES
================================
  There are five BSA files in Daggerfall's ARENA2 directory (ARCH3D, MAPS,
  MONSTER, MIDI, and BLOCKS). Although they contain different data, their
  overall structure is the same. This format has been derived from all these
  five files.  The following description appears to be complete.


    General File Layout
  -------------------------------------  
	BSA Header    	
	...BSA Records...
	BSA Directory


    BSA Header
  -------------------------------------  
    This is the first 4 bytes found at the start of a BSA file and gives
    information about the BSA directory at the end of the file.

	[Bytes 0-1] short DirectoryCount;
		Gives the number of entries in the directory at the end of the 
		file.
	[Bytes 2-3] short DirectoryType; 
		Gives the type of directory at the end of the BSA file (See
		BSA Directory below).
			0x0100 = Directory has records of 18 bytes in size
				 consisting of a 14 byte filename and a long
				 record length.
			0x0200 = Directory has records of 8 bytes in size
				 consisting of long ID and a long record size.

    BSA Records
  -------------------------------------  
    This data will depend on the actual BSA file.  The basic contents for the
    five known BSA files are as follows:
	ARCH3D  = 3D Object Information
	BLOCKS  = Dungeon/town block information
	MAPS    = Location information (towns, dungeon, houses, temples, etc...)
	MONSTER = Monster data (no images)
	MIDI    = HMI formatted music


    BSA Directory
  -------------------------------------
     The directory contains the information needed to access the various data
     records in the BSA file.  The contents of each record depends on the BSA
     file.  In general, the directory gives an identification number/string and
     a record length for each record.  There are two known types of directories
     identified by the DirectoryType bytes in the BSA header (0x0100 and 0x0200).


    BSA 0x0100 Directory (Name)
  -------------------------------------
    The 0x0100 type directory consists of records 18 bytes in size and give a
    record size and 13 byte name for each BSA record.
	
	[Bytes 0-13] char FileName[14];
		The filename which identifies this data section.  Filenames
		are in the usual DOS 8.3 format.
	[Bytes 14-17] long DataSize;
		The size of the data in bytes.  The first record starts at 
		offset 4 in the file, ignoring the 4 bytes of the BSA Header.
		The subsequent section offsets can be calculated from this.


    BSA 0x0200 Directory (Number)
  -------------------------------------
    The 0x0200 type directory consists of records 8 bytes in size and give a
    record size and long identifier for each BSA record.
	
	[Bytes 0-3] long RecordID;
		A long number which assumbly identifies the record somehow.
	[Bytes 4-7] long DataSize;
		The size of the data in bytes.  The first entry starts at 
		offset 4 in the file, ignoring the 4 bytes of the BSA Header.
		The subsequent section offsets can be calculated from this.


  MAPS.BSA
================================
  Overall, the Maps.BSA file contains 61 total regions with a combined total
  of 15251 locations, with 4232 of these being dungeon types.


     General File Layout
   -------------------------------------
     The file starts with a short BSA header followed by the map data as sorted
     by map region (the provinces such as Wayrest, Glenpoint, Daggerfall etc...
     in the game).  Each region is furthur divided into other data sections.  
     Each data section is referenced by a directory entry which occurs at the 
     end of the file as per a usual BSA file.

	BSA Header
        Begin Region
	  Location Offset Section 	} MapPItem
	  Location Record Data		} MapPItem
	  Dungeon Offset Section	} MapDItem
 	  Dungeon Record Data		} MapDItem
	  Table Data			} MapTable
	  Name Data			} MapNames
	End Region
	...Other Regions...
	Map Directory


     Location Offset Section (MapPItem)
   -------------------------------------
     Offset sections appear before each section of town record data.  It is
     merely a list of 4 byte long values which point to the start of a location
     record relative to the end of the offset section.


     Location Record Data (MapPItem)
   -------------------------------------
     Each record is pointed to by one offset record in the preceding offset
     section.  Records are variable length. Contains all locations of the
     region (town, dungeon, house, etc...).

	[Bytes 0-3]	long PreRecordCount
		Gives the number of 6 byte records which follow.  This value
		can be 0x00000000 indicating that no records exist.  The
		record data has no visible effect on the location. Values 
		here range from 0 to 555 (confirmed) (around 20% of location
  		and dungeon records have no prerecords).  Total of 569407
		prerecords in the MAPS.BSA file.
	[Bytes 4...]	unsigned char PreRecords[6]
		The 6 byte record data if there is any.
	[Bytes ...]	Header Information, 0x47 (71) bytes			
		[Bytes 0-3]   	long  OneValue1 = 0x00000001;
			Always this value in both location and dungeon records
			(confirmed).
		[Bytes 4-5]   	short NullValue1;
		[Byte  6]     	char  NullValue2;
			Always 0 (confirmed).		
		[Bytes 7-10]  	long  XPosition;
			Position of the location in game position units.
			Values can range from 51,200 (far West) to around 
			32,389,120 (far	East) (confirmed).
		[Bytes 11-14] 	long  NullValue3;
			Always 0 (confirmed).
		[Bytes 15-18] 	long  YPosition;
			Position of the location in game position units.
			Values can range from around 40,961 (far South) to
			16,332,801 (far North) (confirmed).
		[Bytes 19-22] 	long  Unknown1;
			Location records always have 0x00008000 (32768).
			In dungeon records this value is always 0 (confirmed).
		[Bytes 23-26] 	long  Unknown2;
			Values range from 0 to 18 in location records (is 0 
			~75% of the time).  In dungeon records this value is
			always non-zero in the range 65536 to 589824
			(confirmed).
		[Bytes 27-30] 	long  Unknown3;
			Almost always non-zero in all records.  Location record
			values range from 0 to 1832, dungeon values range from
			0 to 684 (confirmed).
		[Byte  31-32] 	short OneValue2 = 0x0001;
			Always 1 in both dungeon/location records (confirmed).
		[Bytes 33-34] 	short LocationID;
			The unique location ID which is used for quests and
			probably other things.
		[Bytes 35-38]	long NullValue4;
			Always 0 in both dungeon/location records (confirmed).
		[Bytes 39-40]	short Unknown4;
			Always 0 in location records and always 1 in dungeon
			records (confirmed).
		[Bytes 41-44]	long Unknown5;
			Always 0 in location records and takes a variety of
			values in dungeon records (always non-zero) (confirmed).
			These last two might indicate the presence and size
			(or offset to) dungeon specific data.
		[Bytes 45-70] 	char NullValue5[26];
			Always 0 in both dungeon/location records (confirmed).
	[Bytes ...] char LocationName[32]
		Gives the location name.  Data is always 32 bytes in size and
		string should be NULL terminated. Any extra data after the 
		string is ignored. The name is used when you enter the location
		but not used when on the travel map (the Name Table is used for
		that).
	[Bytes ...] char Unknowns[9];
		Unknown values
	[Bytes ...] short PostRecordCount
		Gives the number of records which follow.  Records appear
		to be of fixed length 0x1A (26) bytes.  Always 0x0000 in dungeon
		records.

     From this point on the dungeon/location records differ slightly.

     	Location Records	
        ----------------	
	[Bytes ...] char Unknowns1[5];
		Unknown values.
	[Bytes ...] char LocationPostRecords[26][]
		See the Location PostRecords Format section below.  Each record is
		0x1A (26) bytes in size. 
	[Bytes ...] char AnotherName[32];
		Appears to be another name for the location but its purpose is 
		unknown.  Changing it has no visible effect.
	[Bytes ...] long Unknown6;
		This value is the same as the first 4 bytes in the MapTable for
		the location.  Another location ID perhaps.
	[Bytes ...] char Unknowns2[4];
	[Bytes ...] byte BlockWidth;
	[Bytes ...] byte BlockHeight;
		Range from 1 to 8 and give the size of the location in blocks. The
		BlockWidth*BlockHeight will give the number of block file numbers
		in the following sections.
	[Bytes ...] char Unknowns3[7];
	[Bytes ...] char BlockFileIndex[64];
		Each can be an index, from 0 to 44, of a block file.  See
		Appendix C for more information.  Usually just the first index
		is used and the rest are zero.
	[Bytes ...] char BlockFileNumber[64];
		Similarily gives the block file number, from 0 to 42.
	[Bytes ...] char BlockFileChar[64];
		Similarily gives the block file character, from 0 to 143.  See
		Appendix C for possible values.
	[Bytes ...] char Unknowns4[32];
		Typically zero but almost all values range from 0 to 122.
	[Byte  ...] char Unknown5;
		Ranges from 0 to 18, usually 0.
	[Byte  ...] char Unknown6;
		Ranges from 0 to 22, usually 0.
	[Bytes ...] char NullValues1[9];
		Always 0 (confirmed).
	[Bytes ...] long Unknowns7[22];
	[Bytes ...] char NullValues2[40];
		Always 0 (confirmed).
	[Bytes ...] long Unknown8;


     	Dungeon Records
	---------------
	[Bytes ...] long Unknown6; 
	[Bytes ...] long Unknown7; 
	[Bytes ...] short NumDungeonPostRecords;	
		Gives the number of dungeon post records.
	[Bytes ...] char Unknown8[5]
	[Bytes ...] char DungeonPostRecords[][4];
		Each is 4 bytes in size.
	[Bytes ...] char Padding[];
		Variable size of data which appears to always be zero and may 
		simply be padding for the dungeon post records. The padding
		size is equal to  (128 - NumDungeonPostRecords*4).


2) Location Types

In Appendix B, the location types are listed. 0xAC (172) is listed as Dark Pink, but it looks red to me. In fact, the difference between  0xAC and 0x8C is a mystery.

Looking at the locations corresponding to each of these, I have come up with names for them:

0x84 (132) = Major Dungeon
0x87 (135) = Fortress (Large Dungeon)
0x8A (138) = Ruins (Small Dungeon)
0x8C (140) = Graveyard
0x8D (141) = Coven

0xA0 (160) = Large Town
0xA1 (161) = Medium Town
0xA2 (162) = Small Town
0xA3 (163) = Farmstead
0xA6 (166) = Tavern

0xA5 (165) = Temple
0xA9 (169) = Shrine

0xA8 (168) = Palace / Manor
0xAB (171) = Shack
0xAC (172) = Graveyard

			


     Location PreRecords Sub-Format
   -------------------------------------
     The format for the 6 byte prerecord data found in the location and
     dungeon record data is as follows:
         	
	[Bytes   0-1]	short PostRecordIndex;
		Dungeon Records:
			0xFFFF - Always this value (confirmed)
		Location Records:
			Appears to give be postrecord index which the prerecord
			may apply to. The same index may be repeated in several 
			prerecords.
	[Byte    2]	char  NullValue;
		Always 0x00 in both dungeon/location records (confirmed).
	[Byte    3]	char Unknown3;
		Dungeon Records:
			0x00 - Only 23 records.
			0x10 - About half of records (10334).
			0x40 - About half of records (10415).
			0x80 - Only 17 records.
		Location Records:
			0x10 - About 20% of records (106905).
			0x20 - Around half of records (248908).
			0x30 - Only 100 records.
			0x40 - About 10% of records (59384).
			0x50 - Only 54 records.
			0x60 - Only 53 records.
			0x80 - Only 17 records.
			0xA0 - About 20% of records (133138).
			0xB0 - Only 51 records.
			0xE0 - Only 25 records.
	[Byte    4]	char Unknown4;
		Dungeon Records:
			Always non-zero and usually less than 0x0A but ranges
			up to 0xE7 (231).
		Location Records:
			Takes on a wide range of values 0-0xFF, usually
			non-zero (confirmed).
	[Byte    5]	char Unknown5;
		Dungeon Records:
			0x00 - Only in 32 records
			0x01 - Only in 8 records
			0xFA - Occurs in most records (20749)
		Location Records:
			Usually always less than 0x09 but 166572 records have
			the value 0xFA.

     The arrangement of variables above is arbitrary as the actual purpose of
     data is currently unknown.  PreRecords usually appear in location records.
     Only 20789 (3.7%) of the 569407 total prerecords in MAPS.BSA occur in
     dungeon records.  The number of prerecords is generally smaller in
     dungeon records than location records as well.  Prerecord numbers range
     from 0 to 27 in dungeon records while 0 to 555 in location records. The 
     data has no visible effect on the location.  The data can be mangled or
     simply removed with no apparent effect on the location.


     Location PostRecords Sub-Format
   -------------------------------------
     Records which appear after the location name in the location record are
     0x1A (26) bytes in size and have the format listed below.  Location
     postrecords only occur in location records, not dungeon which have their
     own post record format.  The number of prerecords in location records 
     range from 0 to 329 with a total of 328499 in the MAPS.BSA.  There are
     usually no postrecord information (97%).  

	[Bytes 0-1] 	short HouseNameType;
		Affect the generation of the house name.  Ranges from 0 to
		0x81DD (33245).
			00 00 = The Dancing Chasm (Tavern)
			01 00 = The Knave and Scorpion (Tavern)
			02 00 = The Dancing Chasm (Tavern)
			00 09 = The Silver Scorpion (Tavern)
			BA 29 = The Golden Stag (Tavern)
			BB 29 = People of Alik'r (Temple)
			EA 7E = The Queen's Dungeon (Tavern)
	[Bytes  2-17] 	char NullValues[16];
		Always 0 (confirmed).
	[Bytes 18-19]	short Unknown1;
		Usually zero and ranges from 0 to 852.  Appears to be generally
		zero for residences (unconfirmed).
	[Bytes 20-21]	short Unknown2;
		This value seems to generally increase with each postrecord.
		Changing this number at all crashes the game when the location
		is loaded. Always non-zero and ranges from 4 to 2329.
	[Bytes 22-23]	short LocationID;
		This value is always the same as the location ID in the the 
		location record header (confirmed).
	[Byte 24] 	char HouseType;
		Something to do with the house name or type, ranges from
		0 to 0x18 (24).
			0x0E = Temple
			0x0F = Tavern
			0x10 = Palace
			0x11 = Residence
			0x12 = Residence
			0x13 = Residence
	[Byte 25] 	char Unknown3;
		Always non-zero and ranges from 1 to 0x14 (20).


     Dungeon PostRecords Sub-Format
   -------------------------------------
     The Dungeon PostRecords are each four bytes long and have the following 
     format:

	[Byte 0] signed char x
	[Byte 1] signed char y
	[Byte 2] unsigned char blockNumber (low byte)
	[Byte 3] 
	    [bits 0-1] (high bits of blockNumber)
	    [bit 2] Set to 1 if the player starts in this block, 0 otherwise
	    [bits 3-7] unsigned char blockType

     The blockType is actually an index into a character array at offset 
     001B:3E44 of Fall.exe:

	const char blockTypes[6] = {'N', 'W', 'L', 'S', 'B', 'M'};

     When the appropriate character is concatenated to the seven-digit 
     decimal representation of the blockNumber, the name of an RDB file is 
     constructed. (For example, "N0000019.RDB")

     The x and y values place the block on a 2D grid. Generally, the central 
     block of the dungeon is at (0,0).

     Note: the only file that requires the two extra bits of blockNumber is 
     S0000999.RDB. This file is only used in Privateer's Hold.

     Also note: there are no RDB files that begin with "L" and there are no
     Dungeon Post-Records that refer to L.
		

     Dungeon Offset Section (MapDItem)
   -------------------------------------
     Dungeon Offset sections appear before each section of dungeon record data
     and follow immediately after the end of the town record data for a region.

	[Bytes 0-3] long DungeonCount
		The number of dungeon records which follow.
	[....] Offset Section Records
		Records are 8 bytes in length and have the following structure:
			long Offset   = Offset to record data from end of the
					offset section
			short Number  = 0x0100 usually?
			short Unknown = Another increasing number


     Dungeon Record Data (MapDItem)
   -------------------------------------
     Each record is pointed to by one dungeon offset record in the preceding
     dungeon offset section for the region.  Records are variable length. Only
     locations that are dungeons, ie, that have new interior maps, are included
     here.  Assumably this section defines the map 'blocks' which make up the
     dungeon. For now this appears to be the same as the Location Record Data.
		
	
     Location Table Section (MapTable)
   -------------------------------------
     Contains data related to to the locations in the previous sections for the
     current region.  Starts immediately after the last dungeon record data.
     The number of section records is the number of the towns in the current
     region.  Each record is 17 bytes in size and appears to be a bit field
     (bit fields are identified by the 6.# where # here would represent the
     #th bit in the 6th byte, the 8th bit would be the 0th bit in the next
     byte).
   
	[Byts 0-3]    long Unknown1; (32 bits)
		This number is repeated in the location record.  Perhaps a 
		unique identifier of some sort.
	[Bytes 1-4]   char Unknown2; (8 bits)
		Possibly always 0.
	[Bytes 5-6.1]   unsigned int XPosition; (17 bits)
		Gives the X-position of the location for display on the travel
		map.  One pixel appears to equal 128 units with the origin
		at the bottom-left of the map.  Values should range from
		0 (far left) to 128000 (far right) (unconfirmed). Each unit
		is equal to about 256 position units in the game.
	[Bytes 6.2-8]   int LocationType; (15 bits)
		Type of the location (home, dungeon, town, etc...).  This
		determines the color of the location on the travel map.
	[Bytes 9-10]  unsigned short YPosition; (16 bits)
		Gives the Y-position of the location for display on the travel
		map. Ranges from 0 (map bottom) to 64000 (map top) (unconfirmed).
	[Bytes 11-12] short Value2; (16 bits)
	[Bytes 13-16] long Value3; (32 bits)


     Location Name Section (MapNames)
   -------------------------------------
     Repeats all the town names in the current region.  Each town name is
     32 bytes, NULL terminated, and starts immediately following the town
     name header section.  The town name offset section for the next region
     starts immediately after this town name data.  This is the name used on
     the travel map.

	[Bytes 0-3]  long LocationCount;
		Number of locations in list.  This value might be used to
		determine the total number of locations in a region.
	[Bytes 4...] char Names[32][...];
		All the location names (max 32 characters including NULL
		terminator).


     Map Directory
   -------------------------------------
     The map directory is the last 4464 bytes of the Maps.BSA file and is the 
     usual 0x0100 BSA directory type.  It contains 248 records of 18 bytes each
     (for 62 regions, 000 to 061).  The filenames are of the form
		MAPPITEM.0## - Place item offset data and records
		MAPDITEM.0## - Dungeon offset data and records
		MAPTABLE.0## - Map table
		MAPNAMES.0## - Name table
     where ## ranges from 00 to 61 (for each region).  Assumably the
     DF engine requests the data by this filename. See Appendix A for
     a list of which regions correspond to which values.


  ARCH3D.BSA
================================
  The following description has been tested on all the 3D Objects contained
  in Arch3D.BSA and appears to be sound.  There are two records which have 
  some problems (offsets 0x008B8D58 and 0x013274C6) and don't follow the
  known format of the other 10249 records.  They have a large section of
  repeating bytes just after the 3D object header and their Data2 section
  is not the standard.  These records could very well be corrupt or not 
  used or of a special, undiscovered, format.
  

    General File Layout
  -------------------------------------
    The file is a typical BSA file with a 0x0200 directory at the end. Each
    BSA record contains the information for one 3D object.

	BSA Header
        ...3D Object Records...
	Object Directory


    BSA Header
  -------------------------------------
    A typical, 4 byte, BSA header indicating 0x280B records (10251).


    3D Object Records
  -------------------------------------
    Each BSA record contains the information for one 3D object. Note that each
    record appears to be _similar_ to the .3D file format used in Battlespire. 
    One difference is that here the .3D files are contained in one big file, 
    while in Battlespire they are in individual files. Records range from 212
    to 81394 bytes in size.  The basic record layout is as follows:

	3D Object Header (64 Bytes)
		Always the first 64 bytes in the record.  See the header
		section below for detail format and information.
	Unknown Data		
		Two files have strange sections of repeating bytes between
		the record header and point data. Usually, though, the point
		data follows starting at byte 64.
	Point Data
		Contains the point data as given by the number of points 
		previously read.  Each point is composed of 3 signed long
		integers, (X, Y, Z) for 12 bytes per point. Use the PointOffset
		variable in the header to get the start of the point data.
	PlaneData
		See the Plane Data Record section below.  There is one record
		for each plane given by the PlaneCount variable.  Use the
		PlaneOffset variable in the header to get the start of the
		plane data.
	Normal? Data Section
		Appears to have XYZ 12 bytes triplets again with the number of
		records equal to the number of planes.  This appears to be the
		normals of the planes but not entire confirmed. The offset to
		this data is also in the header.
	Offset1 Data Section
		This section is usually all 0x00's, but the size indicates it
		should have a record size of 24 bytes with the number of
		records equal to the number of planes. The offset to the start
		of this data is also in the header.
	Offset2 Data Section
		The number of records in this section is given in the object
		header.	The basic format of each record is as follows:
		   [Bytes 0-15]		long Numbers[4];
			Looks like 3 or 4 coordinates.
		   [Bytes 16-17]	short NumSubRecords;
			Gives the number of 6 bytes sub-records which follow.
		   [Bytes 18...]	char SubRecords[6][]
			The variable number of sub record data.
		This data finishes off the object record data.  The offset
		to the start of this data and the number of records the section
		contains is in the object header.

    Note that while most 3D objects have this format, some have the sections 
    mixed up slightly (i.e., the data1 section comes before the points).  One
    should use the offset information in the object header to determine where
    each section starts.


    3D Object Header
  -------------------------------------
    The header is always the first 64 bytes in a 3D object record.

    	[Bytes 0-3]	char Version[4] = "v2.7"; (or "v2.6" or "v2.5")
		Appears to be a version number or record identifier. Most of
		the records have v2.7, though 135 have v2.6 and 9 have v2.5.
		Note that the trailing NULL character is not included.  It is
		currently unknown what differences the various version records
		have, although it appears to be minor.
	[Bytes 4-7]	long PointCount;
		Gives the number of points contained in the 3D object.  Each
		point consists of 3 long integers (X, Y, Z) for a total of 
		12 bytes per point.  Point counts range from 3 to 1010.
	[Bytes 8-11]	long PlaneCount;
		This gives the number of planes/faces in the 3D object. Plane
		counts range from 1 to 712.
	[Byte  12-15]	long Unknown1;
		Has a wide range of values, generally non-zero.
	[Bytes 16-23]   char NullValue1[8];
		Always 0x00 bytes (confirmed).
	[Bytes 24-27]	long Data1Offset;
	[Bytes 28-31]	long Data2Offset;
		Appear to be offsets from the start of an object record
		Offset1 is always non-zero and Offset2 is zero only 3 times
		(confirmed).
	[Bytes 32-35]	long NumData2Records;
		Usually non-zero and less than 0x0010 (maximum around 212).
		Appears to be the number of records pointed to by Offset2.
	[Bytes 36-37]	short Unknown3;
		A wide range of repeating values.
	[Bytes 38-39]	short Unknown4;
		Usually 0x0000 or less than 0x0010 (maximum of 0x0068).
	[Bytes 40-43]	long NullValue3;
	[Bytes 44-47]	long NullValue4;
		Always 0x00000000 (confirmed).
	[Bytes 48-51]	long PointOffset;
		Almost always 0x00000040 but also takes on the values
			0x00000000 (strange?)
			0x00000178
			0x00001510
			0x000017F8
		The offset from the start of the object record to the start of
		the point data.
	[Bytes 52-55]	long NormalOffset;
		Offset from the record origin to the next byte after the end of
		the plane data. Always non-zero (confirmed).
	[Bytes 56-59]	long Unknown6;
		Always 0x00000000 except for 19 records which it has a number
		of values from 0x000000F4 to 0x000001FC. Possibly offset?
	[Bytes 60-63]   long PlaneOffset;
		Offset from start of object to the plane/face data.
	

    Plane Data Record Section
  -------------------------------------
    This is a sub-record of the 3D Object Record. Each plane record is 
    (8 + (PlanePointCount*8)) bytes in size. Some of the variables are bit
    fields written out as [Bytes 2-3.1] which would be a 9 bit field.
    
	[Byte 0]	unsigned char PlanePointCount; (8 bits)
		The number of points which makes up the plane. This value
		ranges from 0x00 to 0x18 (24).
	[Byte 1]	char Unknown1;	(8 bits)
		Usually 0x00 for most plane records (about 2% are non-zero).
		Values range from 0x00 to 0xFF although most are repeating 
		values in the 0x00 to 0x40 range.
	[Bytes 2-2.6]	unsigned short SubImageIndex;	(7 bits)
		The subimage index in the texture file (0 to 127).
	[Bytes 2.7-3.7]	unsigned short TextureIndex;	(9 bits)
		The texture file index (0 to 474). 
	[Bytes 4-7] 	long Unknown4;
		Almost always 0x00000000, 0x00010000, 0x00010001, or 0x00010002 
		and rarely a wide range of other values.  Probably two short 
		values.
	[Bytes 8...]	PlanePointSubRecords
		For each point in the PlanePointCount variable, there is 8 bytes
		of data.
			[Bytes 0-3] 	long PointOffset;
			   v2.7:This gives the offset of the point used from the
				beginning of the point data. In other words,
				divide by 12 to get the point index. This is 
				confirmed for all v2.7 objects except for one
				which is strange (offset 0x013274C6).
			   v2.6:Appears to be the same as v2.7.
			   v2.5:The point offset is a multiple of 4 and appears
				to be the offset to the actual XYZ coordinate
				of the point.  To get the point index, divide
				by 4 (unconfirmed).
			[Bytes 4-5]	short TextureU;
			[Bytes 6-7]	short TextureV;
				Specifies the texture UV coordinates for the
				point.  See Appendix E for a complete description
				of how Daggerfall handles UV texture coordinates.


    Object Directory
  -------------------------------------
    The object directory is at the end of the file and gives the record lengths
    of all the 3D object records (the usual 0x0200 type BSA directory map).
    There is also a long value associated with each record which, for most
    entries, is unique (all but 25 of 10251 records have unique values in the
    directory).


    Special Objects
  -------------------------------------
    The following list of objects in the ARCH3D file have special mention.

	Object 4722 (0x8B8D58)
		This v2.6 3D object has a truncated, or different, Data2
		section which does not conform with the known format.
	Object 7614 (0x13274C6)
		This v2.7 object has an invalid offset to the Data2
		section (it points to the middle of the data1 section).


  BLOCKS.BSA
================================
  A typical BSA file with a filename type directory at the end with 1295 
  records.  There are three types of records which are contained in this
  BSA file which can be derived from their directory filenames.
	 FOO.	One record is not any real data but actually a DOS
		directory listing of someones directory (with a hard drive
		named FireBall).
	*.RDB   Variable length record. 187 files.
	*.RDI	Seems to be a fixed length record of 512 bytes. Appears to
		contain only 00's and 01's. 187 files.
	*.RMB	Most records are this type of variable length record. 
		920 files.


    RMB General File Layout
  -------------------------------------
    The RMB file is the most common type in the blocks file and is organized as
    follows:

	RMB File	
		Fixed Length Data (FLD)		(6776 bytes total)
			Record Counts		(3 bytes)
			FLD Header		(640 bytes)
			FLD Section1		(832 bytes)
			FLD Section2		(128 bytes)
			FLD Block Data Sizes	(128 bytes)
			FLD Small Maps		(520 bytes)
			FLD Automap 		(4096 bytes))
			FLD Filenames		(429 bytes)
		...RMB Block Data...		(Variable)
			Outside Header		(17 bytes)		
			  3D Object Data	(66 byte records)
			  Flat Object Data	(17 byte records)
			  Data Section3		(16 byte records)
			  People Data		(17 byte records)
			  Door Data		(19 byte records)
			Inside Header		(17 bytes)
			  3D Object Data	(66 byte records)
			  Flat Object Data	(17 byte records)
			  Data Section3		(16 byte records)
			  People Data		(17 byte records)
			  Door Data		(19 byte records)
			Extra Byte		(1 byte, optional)
		...RMB 3D Objects...		(66 byte records)
		...RMB Flat Objects...		(17 byte records)

    Note that in the RMB block data section there are two repeating sections.
    The first section contains data for the outside, or main, object, such
    as the exterior of a house or tavern.  This section usually just has one
    3D Object Data section which is the main 3D object for locations.  The 
    following section holds the data for the interior object, such as inside 
    a house or tavern.  Typically this section holds much more information
    than the previous one.


    RMB Fixed Length Data (FLD)
  -------------------------------------
    Each block record appears to begin with 0x1A78 (6776) bytes of fixed length
    data.  This data can be subdivided into the follow records.

		FLD Record Count	(3 bytes)
		FLD SubBlock Positions	(640 bytes)
		FLD Section1		(832 bytes)
		FLD Section2		(128 bytes)
		FLD Block Data Sizes	(128 bytes)
		FLD Small Maps		(520 bytes)
		FLD Automap 		(4096 bytes)
		FLD Filenames		(429 bytes)

    In general, each of these subsections can be subdivided into 32 further 
    subrecords as described in each section below.


    RMB FLD Record Counts
  -------------------------------------
    The first 3 bytes in the fixed length data give the number of various
    records which appear later on in the block record.

	[Byte 0]  byte NumSubRecords1;
		Values range from 0 to 28 with a total of 9005 subrecords1 in 
		the blocks file.
	[Byte 1]  byte NumSubRecords2;
		Values range from 0 to 93 with a total of 9153 subrecords2
		in the blocks file.
	[Byte 2]  byte NumSubRecords3;
		Values range from 0 to 74 with a total of 11732 subrecords3
		in the blocks file.


    RMB FLD Block Positions 
  -------------------------------------
    The fixed length data header is found at offsets 0x03 to 0x282 (642) bytes
    in the FLD for a total of 0x280 (640 bytes). It contains 32 records of
    0x1A (20) bytes each which contain the positions for each of the sub-blocks
    in the file.
		[Bytes  0 - 3]	long XPos1;
		[Bytes  4 - 7]	long ZPos1;
			Unknown what these coordinates are for. Possibly the 
			subblock size?
		[Bytes  8 -11]  long XPos2;
		[Bytes  12-15]  long ZPos2;
			Give the position of the subblock in map coordinates.
		[Bytes 16-19]	long YPos2;
			Unknown.
   

    RMB FLD Section1 
  -------------------------------------
    The fixed length data section1 is found at offsets 0x283 (643) to 
    0x5C2 (1474), just after the FLD header, for a total of 0x340 (832) bytes.
    It seems to contain 32 records of 0x1A (26) bytes each.  It seems to
    be very similar to the location post-records found in MAPS.BSA.
	

    RMB FLD Section2
  -------------------------------------
    The fixed length data section2 is found at offsets 0x5C3 (1475) to 
    0x642 (1602), just after the FLD Section1, for a total of 0x80 (128) bytes.
    It should contain 32 records of 4 bytes each. 


    RMB FLD Block Data Sizes
  -------------------------------------
    This section is found at offsets 0x5C3 (1475) to 0x6C2 (1730), just after
    the FLD Section2, for a total of 0x80 (128) bytes. It contains 32 records
    of 4 bytes each and represents the record sizes of the Block Data records
    which appear later in the file.
		
		[Bytes 0-127]	long Sizes[32];


    RMB FLD Small Map Data 
  -------------------------------------
    The fixed length data section3 is found at offsets 0x6C3 (1731) to 
    0x8CD (2253), just after the FLD Block Data Sizes, for a total of 
    0x208 (520) bytes. It appears to contain an 8 byte header followed by
    two sections of 256 bytes each.  
		
	[Bytes   0-  7]	char Header[8];
	[Bytes   8-263]	char TextureInfo[16][16];
		See description which follows. Contains modified texture
	     	image indices to use.
	[Bytes 264-519]	char ObjectInfo[16][16];
		Currently unknown.

    The first 256 bytes after the header shows some interesting designs when 
    viewed as a 16x16 image and probably indicates the textures to display on
    the land under the block.  The format for the texture info bytes is a bit
    field described as follows:

	[Bits 0-5]  int	TextureIndex;	(6 bits)
		This value, ranging from 0-63, gives the new texture index to
		display. The texture file to use will depend on the current 
		location (desert, temperate, etc...) and the time (raining,
		summer, winter, etc...).  
	[Bit    6]  int RotateTexture;	(1 bit)
		Might be a flag indicating that the texture should be rotated
		90 degrees so that the width becomes its height and vice-versa.
		This allows reuse of textures rather than duplicating them in
		the texture file.
	[Bit    7]  int FlipTexture;	(1 bit)
		Appears to be a flag indicating that the texture should be
		flipped in both the X and Y directions so that its last pixel
		becomes its first.

    The last 256 bytes looks more like a starry night and could indicate how to
    place scenery around the block, but its purpose is unknown currently. It may
    be a bit field like the first 256 byte section.
    

    RMB FLD Automap
  -------------------------------------
    The fixed length data section4 is found at offsets 0x8CB (2251) to 
    0x18CA (6346), just after the FLD Small Map Data, for a total of 0x1000 (4096)
    bytes. It contains a 64x64 bitmap which is seen when you look at the 
    automap while in town.  The bitmap also contains extra information which
    is not displayed.  The general pixel values are as follows:
	
		0x00 	Background, transparent
		0x03	Store? (orange)
		0x10	Taverns (green)
		0x12	Residence? (gray)
		0x13	Residence (gray)
		0x14	Residence? (gray)
		0xE0	Special Item? (not displayed)
		0xFA	Object (not displayed)
		0xFB	Object (not displayed)

    It is not known what the three types of residences represent.  The bitmap
    probably does not control where things appear but was most likely used as
    as development tool.


    RMB FLD Filenames
  -------------------------------------	
    The list of component filenames is found at offset 0x18CB (6347) to
    0x1A77 (6775), just after the FLD Section4, for a total of 0x1AD (429)
    bytes. Filenames are 13 bytes which includes the terminating NULL
    character (regular 8.3 syntax). There may be NULL filenames at the end
    of the list.  The first filename is always the block record file followed
    by 32 other filenames.

	[Bytes  0- 12]	char BlockFilename[13];
	[Bytes 13-428]  char Filenames[13][32];


    RMB Block Data
  -------------------------------------	
    Following the FLD section there are usually one or more blocks of block
    data which can be described as follows:

	Header			(17 bytes)	     }	Exterior data like that
	  3D Object Data	(66 byte records)    }  for a house or tavern. 
	  Flat Object Data	(17 byte records)    }  Usually contains just 
	  Data Section3		(16 byte records)    }  one 3D object 
	  People Data		(17 byte records)    }	
	  Door Data		(19 byte records)    }
	Header			(17 bytes)	   	} Interior data like 	
	  3D Object Data	(66 byte records)	} that for the inside
	  Flat Object Data	(17 byte records)	} of a house or tavern.
	  Data Section3		(16 byte records)	} Contains much more 
  	  People Data		(17 byte records)	} data than the previous
	  Door Data		(19 byte records)	} section.
	Extra Byte		(Optional 1 byte, 0x96)

    Some RMB files do not have any subrecords, they simply end after their FLD
    Filenames.  In some subrecords there is an extra byte, 0x96, after the end
    of the record.  It can be identified by the length of the subrecord1 as
    given in the fixed length data section for the RMB file.


    RMB Block Header
  -------------------------------------	    
    The header is always at the start of the block subrecord and appears to be
    always 0x11 (17) bytes in size.

	[Byte      0]	unsigned char Num3DObjectRecords;
	[Byte      1]	unsigned char NumFlatObjectRecords;
	[Byte      2]	unsigned char NumSection3Records;
	[Byte      3]	unsigned char NumPeopleRecords;
	[Byte      4]	unsigned char NumDoorRecords;
		The number of records in each of the data sections which follow.
	[Bytes  5- 6]	short Unknown1;
	[Bytes  7- 8]	short Unknown2; (always non-zero)
	[Bytes  9-10]	short Unknown3;
	[Bytes 11-12]	short Unknown4; (always non-zero)
	[Bytes 13-14]	short Unknown5; (always non-zero)
	[Bytes 15-16]	short Unknown6; (always non-zero)
		The data suggests 3 pairs of shorts but it could be something
  		entirely different.


    RMB Block Record 3D Object Data
  -------------------------------------	    
    The data follows immediately after the block header and is composed of 
    0x42 (66) byte records.  It contains the 3D object information for the
    current block.

	[Bytes  0- 1]	short ObjectID1;
		Always non-zero in the range 1-511. 
	[Byte      2]	char  ObjectID2;
		Ranges from 0 to 63.
		The required 3DObject to load from Arch3D.BSA can be calculated
		from:
				ObjectID1 * 100 + ObjectID2

		This appears to give the directory ID for the appropiate object.
		It may be done this way if the objects are grouped by type in
		some fashion.
	[Byte      3]	char  Unknown1;
		Always non-zero, ranges from 3 to 67.
	[Bytes  4- 7]	long Unknown2;
		Non-zero only in 1297 of 236250 records. Seems to repeat within
		the same file.  Could be two or four seperate fields.
	[Bytes  8-13]	long Unknown3;
	[Bytes 14-17]	long Unknown4;
		Non-zero only in 272 of 236250 records. Seems to repeat within
		the same file.  Could be two or four seperate fields.
	[Bytes 16-19]	long NullValue1;
	[Bytes 20-23]	long NullValue2;
		Always 0 (confirmed).
	[Bytes 24-27]	long XPos1;	( -896256 to 761856 )
	[Bytes 28-31]	long YPos1;	(  -59136 to 273152 )
	[Bytes 32-35]	long ZPos1;	( -815360 to 705536 )
		Usually 0s, but some (370) records have what look like
		coordinates here with the given ranges.
	[Bytes 36-39]	long XPos2;	( -1088 to 1096 )
	[Bytes 40-43]	long YPos2;	(  -579 to  518 )
	[Bytes 44-47]	long ZPos2;	(  -512 to 1536 )
		Looks to be a coordinate of some form.  Values range as
		indicated above and is usually non-zero.
	[Bytes 48-51]	long NullValue3;
		Always 0 (confirmed).
	[Bytes 52-53]	short Angle;
		Almost always non-zero.  A value of 0x200 specifies that the
		object should be rotated 90 degrees about the Y-Axis (vertical).
	[Bytes 54-55]	short Unknown5;
		Always zero.
	[Bytes 56-59]	long NullValue6;
		Always 0 (confirmed).
	[Bytes 60-63]	long Unknown8;
		Only non-zero 16 times in one file (CUSTAA45.RMB) where it is
		0x200 (512).
	[Bytes 64-65]	short NullValue5;
		Always 0 (confirmed).


    RMB Block Flat Objects
  -------------------------------------	    
    This data follows immediately after the 3D Object Data in a Block Record 
    and is composed of 0x11 (17) byte records.  It contains information about
    flat objects in the block.  Flat objects are just that, merely textures 
    painted on planes which always face the viewer (called decals in Direct3D).

	[Bytes 0- 3]		long XPos;
	[Bytes 4- 7]		long YPos;
	[Bytes 8-11]		long ZPos;
		Looks like coordinate of some form.
	[Bytes 12-12.6]		int SubImageIndex;	(7 bits)
		The subimage in the texture file to use for the flat.
	[Bytes 12.7-13.7]	int TextureIndex;	(9 bits)
		The texture file index to use.
	[Bytes 14-15]		short Unknown1;
		Usually non-zero (50%) and ranges from 0 to 65535. Might 
		indicate whether or not to display the flat.  The 'debuging'
		icons usually have a value of 0x0000 or 0xFFFF here.
	[Byte     16]		char  Unknown2;
		Usually non-zero (90%) and ranges from 0 to 105.


    RMB Block Data Section3
  -------------------------------------	    
    This data follows immediately after the Flat Objects Data and is
    composed of 0x10 (16) byte records. It has an unknown purpose.

	[Bytes  0- 3]	long XPos;
	[Bytes  4- 7]	long YPos;
	[Bytes  8-11]	long ZPos;
		Looks like coordinate of some form.
	[Byte     12]	char  Unknown1;
		Usually zero (99%) and ranges from 0 to 15.  Repeats mostly
 		in each file where it is present.
	[Byte     13]	char  Unknown2;
		Almost always non-zero and ranges from 0 to 45.
	[Bytes 14-15]	short Unknown3;
		Usually zero and ranges from 0 to 1292.  Lower 8 bits are
		always zero and upper 8 bits range from 0 to 7.


    RMB Block People Data
  -------------------------------------	    
    This data follows immediately after the Section3 Data in a Block record and
    is composed of 0x11 (17) byte records.  Appears to be the same format as
    the Flat Object data.  It contains information about the people in a block.

	[Bytes 0- 3]		long XPos;
	[Bytes 4- 7]		long YPos;
	[Bytes 8-11]		long ZPos;
		Looks like coordinate of some form.
	[Bytes 12-12.6]		int SubImageIndex;	(7 bits)
		The subimage in the texture file to use for the person.
	[Bytes 12.7-13.7]	int TextureIndex;	(9 bits)
		The texturefile to use for the person.
	[Bytes 14-15]		short NPCType;
		Seems to indicate the type of PC such as weaponsmith, barkeep.
		etc...
			0x0000 - Common person
			0x01FE - Barkeep
	[Byte     16]		char  Unknown3;
		Always non-zero and ranges from 1 to 45.


    RMB Block Door Data
  -------------------------------------	    
    This data follows immediately after the People Data in a Block and is
    composed of 0x13 (19) byte records.  It seems to give information about
    the movable doors in a block.
	
	[Bytes 0- 3]	long XPos;
	[Bytes 4- 7]	long YPos;
	[Bytes 8-11]	long ZPos;
		Looks like coordinate of some form.
	[Bytes 12-13]	short Unknown1;
		Usually non-zero in the range 0 to 1536.
	[Bytes 14-15]	short Unknown2;
		Always non-zero in the range 90 to 98.
	[Bytes 16-17]	short Unknown3;
		Almost always non-zero in the range 0 to 7173.
	[Byte     18]	char  NullValue1;
		Always 0 (confirmed).


    RMB 3D Objects
  -------------------------------------	
    These appear to be the same format as the RMB Blocks 3D Objects which
    are 0x42 (66) byte records.  It probably lists the 3D Objects which
    populate the exterior of a block, such as outside a house or tavern
    (fences, signs, etc...).


    RMB Flat Objects
  -------------------------------------	
    These appear to be the same format as the RMB Block Flat Objects
    are 0x11 (17) byte records.  It probably gives the Flat Objects which
    appear outside the given block, such as grass, bushes, etc...


     RDB Files
  -------------------------------------
     RDB files are archived in Blocks.bsa. Each BSA filename begins with a
     letter and is followed by a 7-digit decimal integer. (For example, 
     "N0000019.RDB") These files are referenced in the dungeon records of 
     Maps.bsa.

     Each RDB file describes one dungeon 'block' in detail. Each block of 
     dungeon is fits on a 2D grid with other blocks. There are two connecting
     passages in each of the four cardinal directions, so there are eight paths
     leading out of each block.

     RDB General Format
  -------------------------------------
	[Header]
	[3D Models Section]
	    [3D Model Records]
	    [Additional Data]
	[Object Section]
	    [Object Header Section]
	    [Object Roots Section]
	    [Object Data Section]

     RDB Header (20 bytes):
  -------------------------------------
	[Byte 0]      char Unknown1;
	[Byte 1]      char Unknown2;
	[Bytes 2-3]   short Unknown3;
	[Bytes 4-7]   long GridWidth;
	    The width of the Object Root Section
	[Bytes 8-11]  long GridHeight;
	    The height of the Object Root Section
	[Bytes 12-15] unsigned long objectOffset;
	    The offset from the beginning of the RDB file to the Object
	    Root Section
	[Bytes 16-19] long Unknown4;


     RDB 3D Models Section (9000 bytes):
  -------------------------------------
     First is a list of 750 3D Model Records of 8 bytes each. Unused records are
     filled with 0xFF. Each record has the following format.

     3D Model Record (8 Bytes)
     -------------------------
	[Bytes 0-4] char modelID[5];
	    a string containing the five-digit decimal representation of
	    the object's model ID
	    as seen in Arch3D.bsa
	    (not null-terminated)
	[Bytes 5-7] char objectType[3];
	    a short string possibly describing the type of object
	    (not null-terminated)

     Additional Data:
  -------------------------------------
	Next is another list of 750 records, but of only 4 bytes each.
	They seem to correspond to the 3D Model Records. The format of 
 	these bytes is unknown. Unused records are filled with 0x00.


     RDB Object Section:
  -------------------------------------
     The Object Section is organized as follows:
	[Object Header Section]
	[Object Roots Section]
	[Object Data Section]


     RDB Object Header Section (512 bytes):
  -------------------------------------
	[Bytes 0-3]   long UnknownOffset;
	    An offset from the beginning of the RDB file to a linked list
	    of unknown purpose and format.
	[Bytes 4-7]   long Unknown1;
	[Bytes 8-11]  long Unknown2;
	[Bytes 12-15] long Unknown3;
	[Bytes 16-19] long FileSize;
	    The length of the RDB file, in bytes.
	[Bytes 20-51] char Unknown4[32];
	    Seem to always be 0xFF
	[Bytes 52-55] char TagDAGR[4];
	    Seem to always be the character array "DAGR"
	[Bytes 56-511] char Unknown5[456];
	    Seem to be 0xFF

     RDB Object Roots Section:
  -------------------------------------
	[Bytes 0-...] long Offsets[]

     The number of longs in the list is GridWidth*GridHeight. Each entry is an
     offset from the beginning of the file to an Object Record. Any negative 
     value indicates that no object data is present. The meaning of the grid 
     layout is unknown.

     RDB Object Data Section:
  -------------------------------------
     This section contains numerous records of various types, not in any 
     particular order.

     Each Object Record is a node of a doubly linked list. Use the
     Object Roots Section to find the head of the list, and iterate
     using the offsetNext and offsetPrev fields.

     Object Record (25 bytes):
	[Bytes 0-3]   long offsetNext;
	    The offset from the beginning of the RDB file to the next
	    Object Record. Any negative value indicates that there is no next item.
	[Bytes 4-7]   long offsetPrev;
	    The offset from the beginning of the RDB file to the previous Object Record.
	    Any negative value indicates that there is no previous item.
	[Bytes 8-11]  long xLoc;
	[Bytes 12-15] long yLoc;
	[Bytes 16-19] long zLoc;
	    These three values define the object's location in space.
	[Byte 20]        char objectType;
	    This can take on only these three values:
	        0x01: The object is a 3D model.
	        0x02: The object is a light source.
	        0x03: The object is a flat (including markers and monsters).
	[Bytes 21-24] long postRecordOffset;
	    The offset from the beginning of the RDB file to the
	    object's type-specific data.

     Each object has a variable length post record, pointed to by
     postRecordOffset. The format of this record depends on the objectType.

     Object Post Record, type 0x01 (3D Object) (23 bytes):
	[Bytes 0-3]   long xAngle;
	[Bytes 4-7]   long yAngle;
	[Bytes 8-11]  long zAngle;
	    the rotation angles about each axis
	[Bytes 12-13] short ModelIndex;
	    Indexes one of the 750 entries in the 3D Models Section.
	    This model is used for the object.
	[Bytes 14-17] long Unknown3; (ranges from 0 to 240)
	[Byte 18]     char Unknown4; (ranges from 0 to 108)   
	[Bytes 19-22] long ActionOffset;
	    Offset from the beginning of the RDB file to an Action
 	    Record, which contains additional information about how this
	    object behaves. If this value is -2 then no such record exists
	    for this object.

     Object Post Record, type 0x02 (Light Source) (10 bytes):
	[Bytes 0-3]   long Unknown1;
	[Bytes 4-7]   long Unknown2;
	[Bytes 8-9]   short Unknown3;
	    (Presumably, these values determine light intensity, range, etc.)

     Object Post Record, type 0x03 (Flat Object) (11 bytes):
	[Bytes 0-1] {
	    [bits 0-6]   int SubImageIndex;        (7 bits)
	    [bits 7-15]  int TextureIndex;        (9 bits)
	}

     The texture to use, formatted as in the "RMB Block Flat
     Objects" section of an RMB file. The TextureIndex identifies
     the texture file and the SubImageIndex identifies the image
     within the texture file.
	[Bytes 2-10]    char Unknown1[9];



     RDB Action Record (10 Bytes):
  -------------------------------------
     3D objects may point to an Action Record in ActionOffset.

	[Bytes 0-4] char DataEntry[5];
	[Bytes 5-8] long TargetOffset;
	    The offset from the beginning of the RDB file to the Object
	    Record describing this action's target, negative if there is no target.
	[Byte 9]    char Type;
	    Probably affects how the DataEntry field is interpreted.
	    Ranges from 0 to 100, but most entries use these values:
	        0x00: Probably used to indicate no action.
	        0x01: Object Translation
	        0x08: Object Rotation

     The target object (and the target object of its action, etc.) is
     activated simultaneously with this object. In this way targets can be
     chained together for several simultaneous effects.

     Both Rotation and Translation actions format the DataEntry
     field in this way:

	[Byte 0]       char Axis;
	    Takes on values ranging from 1 to 99, but most entries
	    use these values:
	        0x01: negative x
	        0x02: positive x
	        0x03: negative y
	        0x04: positive y
	        0x05: negative z
	        0x06: positive z
	    (Maybe a bit field?)
	[Bytes 1-2] unsigned short Duration;
	    Determines how long the object takes to reach its destination.
	[Bytes 3-4] unsigned short Delta;
	    The amount to move along/around the specified axis.

     Rotations rotate about the Axis while translations move along them.

     Doors do not appear to use the Action Record. It is not
     known whether teleporting walls use it. Switches, levers, and
     moving platforms appear to use it.

     For example, in Privateer's Hold there is a switch next to a platform
     with a throne on it. Flipping the switch invokes the switch's action,
     which rotates it into the flipped position. That action targets the
     platform, which makes it rise. The platform's action targets the throne,
     which also rises. All these are performed simultaneously.



  Appendix A - REGION NUMBERS
================================
  The following is a list of region numbers which is used to access the region
  map data in the Maps.BSA file (and possibly elsewhere). Note that some of the
  names are not used in the game (marked by an *).

	00 = Alik'r Desert
	01 = Dragontail Mountains
	02 = Glenpoint Foothills*
	03 = Daggerfall Bluffs*
 	04 = Yeorth Burrowland*
	05 = Dwynnen
	06 = Ravennian Forest*
	07 = Devilrock*
	08 = Malekna Forest*
	09 = Isle of Balfiera
	10 = Bantha*
	11 = Dak'fron
	12 = Islands in the Western Iliac Bay*
	13 = Tamarilyn Point*
	14 = Lainlyn Cliffs*
	15 = Bjoulsae River*
	16 = Wrothgarian Mountains
	17 = Daggerfall
	18 = Glenpoint
	19 = Betony
	20 = Sentinel
	21 = Anticlere
	22 = Lainlyn
	23 = Wayrest
	24 = Gen Tem High Rock village*
	25 = Gen Rai Hammerfell village*
	26 = Orsinium Area
	27 = Skeffington Wood*
	28 = Hammerfell bay coast*
	29 = Hammerfell sea coast*
	30 = High Rock bay coast*
	31 = High Rock sea coast
	32 = Northmoor
	33 = Menevia
	34 = Alcaire
	35 = Koegria
	36 = Bhoriane
	37 = Kambria
	38 = Phrygias
	39 = Urvaius
	40 = Ykalon
	41 = Daenia
	42 = Shalgora
	43 = Abibon-Gora
	44 = Kairou
	45 = Pothago
	46 = Myrkwasa
	47 = Ayasofya
	48 = Tigonus
	49 = Kozanset
	50 = Satakalaam
	51 = Totambu
	52 = Mournoth
	53 = Ephesus
	54 = Santaki
	55 = Antiphyllos
	56 = Bergama
	57 = Gavaudon
	58 = Tulune
	59 = Glenumbra Moors
	60 = Ilessan Hills
	61 = Cybiades


  Appendix B - LOCATION TYPES
================================
  The following is a list of location types used in the map tables. The list is
  not yet exhaustive.

    Dungeons
  ---------------------
	0x84 (132) = Orange,		Major Dungeon
	0x87 (135) = Dark Orange,	Fortress (Large Dungeon)
	0x8A (138) = Medium Red,	Ruins (Small Dungeon)
	0x8C (140) = Dark Red,		Graveyard
	0x8D (141) = Black,		Covens
	

    Towns
  ---------------------
	0xA0 (160) = Light Rose, 	Large Town
	0xA1 (161) = Medium Rose,	Medium Town
	0xA2 (162) = Medium Rose,	Small Town
	0xA3 (163) = Medium Rose,	Farmstead
	0xA6 (166) = Dark Rose,		Tavern

    Temples
  ---------------------
	0xA5 (165) = Light Blue,	Temple
	0xA9 (169) = Dark Blue,		Shrine

    Homes
  ---------------------
	0xA8 (168) = Light Pink,	Palace / Manor
	0xAB (171) = Dark Pink,		Shack
	0xAC (172) = Dark Pink/Red	Graveyard (same as 0x8C?)


  Appendix C - BLOCK INDICES
================================
  At offset 0x1BD97F in v2.13 FALL.EXE, there's a listing of 45 RMB files in
  the format "TVRN????.RMB" to probably be used with a printf() type function
  to generate the appropiate entry to load from BLOCKS.BSA. The filename list
  is as follows (13 bytes per record, 8.3 filenames, terminated by a NULL):

	Index     Filename	 File Chars	File Index	Description
	-----  --------------   ------------	----------   ------------------
	  0	TVRN????.RMB   	A/B/G, L/M/S      0-10		Taverns
	  1	GENR????.RMB	A/B/G, L/M/S      0-3       	General Stores
 	  2	RESI????.RMB	A/B/G, L/M/S      0-10		Residences
	  3	WEAP????.RMB    A/B/G, L/M/S      0-3		Weaponsmiths
 	  4	ARMR????.RMB	A/B/G, L/M/S      0-3		Armourers
	  5	ALCH????.RMB    A/B/G, L/M/S      0-3		Alchemists
	  6	BANK????.RMB    A/B/G, L/M/S      0-3		Banks		
	  7	BOOK????.RMB	A/B/G, L/M/S      0-3		Bookstores
	  8	CLOT????.RMB	A/B/G, L/M/S      0-3		Clothing Stores
          9	FURN????.RMB	A/B/G, L/M/S      0-3		Furniture Stores
	 10	GEMS????.RMB	A/B/G, L/M/S      0-3		Jewelers
	 11	LIBR????.RMB	A/B/G, L/M/S      0-3		Libraries
	 12	PAWN????.RMB	A/B/G, L/M/S      0-3		Pawnshops
	 13	TEMP????.RMB	   AA, GG        00-H0		Temples	
	 14	TEMP????.RMB	   AA, GG        00-H0		Temples	
	 15	PALA????.RMB    A/B/G, A	  0-4		Knight Guilds?
	 16	FARM????.RMB	     AA           0-9		Farms
	 17	DUNG????.RMB	     AA           0-18		Dungeons
	 18	CAST????.RMB         AA           0-34		Unknown
	 19	MANR????.RMB	A/B/G, L/M/S      0-3		Manors?
	 20	SHRI????.RMB         AA		  0		Shrines?
	 21	RUIN????.RMB	     AA           0-28	 	Ruins?
	 22	SHCK????.RMB	     AA		  0		Unknown
	 23	GRVE????.RMB	    A, L/M/S	  0-42		Unknown
	 24	FILL????.RMB	     AA		  0-15		Unknown
	 25	KRAV????.RMB	A/B/G, L	  0-1		Unknown
	 26	KDRA????.RMB	A/B/G, L	  0-1		Unknown
	 27	KOWL????.RMB	A/B/G, L	  0-1		Unknown
	 28	KMOO????.RMB	A/B/G, L	  0-1		Unknown
	 29	KCAN????.RMB	     -		   -		No Files	
	 30	KFLA????.RMB	A/B/G, L	  0-1		Unknown
	 31	KHOR????.RMB	A/B/G, L	  0-1		Unknown
	 32	KROS????.RMB	A/B/G, L	  0-1		Unknown
	 33	KWHE????.RMB	A/B/G, L	  0-1		Unknown
	 34	KSCA????.RMB	A/B/G, L	  0-1		Unknown
	 35	KHAW????.RMB	A/B/G, L	  0-1		Unknown
	 36	MAGE????.RMB	A/B/G, A	  0-14		Mage Guilds
	 37	THIE????.RMB	    A, L/M/S	   0		Thief Guilds
	 38	DARK????.RMB	     AA	   	  0-2		Dark Brotherhood
	 39	FIGH????.RMB    A/B/G, A/L/M/S	  0-2		Fighter Guilds
 	 40	CUST????.RMB	  A/G, A	  0-56		Custom?
	 41	WALL????.RMB	     AA	  	  0-11		Walls?
	 42	MARK????.RMB	A/B/G, A/L/M/S	  0-1		Unknown
	 43	SHIP????.RMB	     AA	   	  0-1		Ship
	 44	WITC????.RMB	     AA	  	  0-13		Witch Covens

  File chars fill in the first two ?? and the file index fills in the last two
  ??.   A value of "A/B/G, L/M/S" means the file characters could be one of
  AL, AM, AS, BL, BM, BS, GL, GM, or GS.  The descriptions given are a rough
  guess based on the RMB file name. The known values for the file chars as
  given in location post records in MAPS.BSA are shown below.

	Value	File Char
	----	--------
	0x00	  AA
	0x01	  AA
	0x02	  AA
	0x07	  AA
	0x0F	  DA
	0x11	  DA
	0x13      DA
	0x15      DA
	0x1F	  DA
	0x2F	  AL
	0x3F	  DL
	0x4F	  AM
	0x5F	  DM
	0x6F	  AS
	0x7F	  DS
	0x8F	  AA
	0x9F      DA

  The 'D' values are strange in that there are no RMB files that have a D in
  the fifth character position.


  Appendix D - COORDINATE LIMITS
================================
  Coordinates are roughly in centimeters as given in the game by using the
  ' cheat key for quest info. Coordinates are 256 times smaller than
  the coordinates used for the 3D objects.

	X = 0? (As far West as you can go)
	X = 32,400,000 (As far East as you can go on the map)
	Z = 2,000,000 (As far South as you can go on the map)
	Z = 16,367,616 (As far North as you can go)


  Appendix E - UV TEXTURE COORDINATES
======================================
  Note: Much of this information orginated from Craig (cpeterson@ematic.com)
  and Gavin (interkarma@m0use.net, http://m0use.net/~interkarma).

  Daggerfall handles UV coordinates a little differently than most 3D programs
  and require some explanation.  The TextureU and TextureV in the plane sub-
  records hold the texture coordinate data for the face point but, depending
  on the face, the UV coordinates have different meaning:

	Point 1: The actual DfUV coordinate for that point.
	Point 2: The change in DfUV coordiantes relative to Point 0.  To get
		 the absolute DfUV values you must add Point 1s to Point 0.
	Point 3: The change in DfUV coordiantes relative to Point 1.  To get
		 the absolute DfUV values you must add Point 2s to Point 1
		 and 0.
	Point 4: For faces with more than 3 points, this point is the absolute
		 DF UV coordinate for that point.  Tests seem to indicate,
		 though, that the game does not use this data.
	Point 5+:UV coordinates should be all 0 and are not used.

  Since all points on the face after the 4th have no UV values, this indicates
  that we must find a relationship between the XYZ point and the UV coordinate,
  which is detailed below.

  The units of DfUV texture coordinates are relative to the size of the texture
  image.  A value of 1024 represents 64 pixels of image data. The conversion
  between DfUV and standard UV coordinates is detailed below.

  
    CONVERTING XYZ to UV Coordinates
  -------------------------------------
  Unfortunately, as of this point, there is no simple way to compute the UV
  coordinate of a point from its XYZ location, but the best current method is
  explained as follows.  We first assume that the relationship is linear and
  of the form:
		U = aX + bY + cZ + d
		V = eX + fY + gZ + h
  
  Since all faces have at least 3 points (confirmed) and we know the UV
  coordinates for the first 4 points, we should be able to solve for the 
  parameters a...h. We assume d and h are both 0 for this case, though we
  will use them later.  We could solve for the 6 unknowns explicitly but we
  would have to take into account which points have similar XYZ coordinates 
  which becomes messy (we can't divide by X1-X2 if they are equal).  Instead, 
  we will take the similar route of expressing the equations in matrix form
  and solving the matrix equation (which may turn out to be just as complex).
  The matrix equation for U is of the form:

	{ X1 Y1 Z1 }   { a }   { U1 }
	{ X2 Y2 Z2 } * { b } = { U2 }
	{ X3 Y3 Z3 }   { c }   { U3 }

  where X1,Y1,Z1,U1 and the coordinates of the first points.  To solve for
  the unknown matrix {a..c} we simple need the inverse of the {X1...Z3} matrix
  which will be multiplied to left of the {U1..U3} matrix.  Using the Jacobian
  method of matrix inversion we can find the solution to be:

		/* Compute the determinant of the XYZ matrix */
	Determinant = X1*Y2*Z3 + Y1*Z2*X3 + Z1*X2*Y3 - X3*Y2*Z1 - X2*Y1*Z3 - X1*Y3*Z2
	
		/* Compute the inverse of the XYZ matrix */
	Xi1 = ( Y2*Z3 - Y3*Z2) / Determinant
	Xi2 = (-X2*Z3 + X3*Z2) / Determinant
	Xi3 = ( X2*Y3 - X3*Y2) / Determinant

	Yi1 = (-Y1*Z3 + Y3*Z1) / Determinant
	Yi2 = ( X1*Z3 - X3*Z1) / Determinant
	Yi3 = (-X1*Y3 + X3*Y1) / Determinant

	Zi1 = ( Y1*Z2 - Y2*Z1) / Determinant
	Zi2 = (-X1*Z2 + X2*Z1) / Determinant
	Zi3 = ( X1*Y2 - X2*Y1) / Determinant

		/* Compute the DfUV conversion parameters */
  	a = U1*Xi1 + U2*Yi1 + U3*Zi1
	b = U1*Xi2 + U2*Yi2 + U3*Zi2
	c = U1*Xi3 + U2*Yi3 + U3*Zi3
	d = 0

	e = V1*Xi1 + V2*Yi1 + V3*Zi1
	f = V1*Xi2 + V2*Yi2 + V3*Zi2
	g = V1*Xi3 + V2*Yi3 + V3*Zi3
	h = 0

  This works for more than 90% of the 10251 objects in the ARCH3D.BSA files,
  but it fails when the Determinant above is 0.  This usually occurs when all
  of the points on a face lie in the X, Y, or Z plane (ie, the X/Y/Z coordinates 
  are identical for all points in the face).  In these cases we must use the d 
  and h parameters which were previously assumed to be zero. For example, in the
  case where all Y's are equal, the equations turn into:

	U = aX + cZ + d
	V = eX + gZ + h

  as b and f are irrelevant due to Y=0.  The matrix solution then becomes:

	{ X1 1 Z1 }   { a }   { U1 }
	{ X2 1 Z2 } * { d } = { U2 }
	{ X3 1 Z3 }   { c }   { U3 }

	Determinant = X1*Z3 + Z2*X3 + Z1*X2 - Z1*X3 - X2*Z3 - X1*Z2

	Xi1 = ( Z3 - Z2) / Determinant
	Xi2 = (-X2*Z3 + X3*Z2) / Determinant
	Xi3 = ( X2 - X3) / Determinant

	Yi1 = (-Z3 + Z1) / Determinant
	Yi2 = ( X1*Z3 - X3*Z1) / Determinant
	Yi3 = (-X1 + X3) / Determinant

	Zi1 = ( Z2 - Z1) / Determinant
	Zi2 = (-X1*Z2 + X2*Z1) / Determinant
	Zi3 = ( X1 - X2) / Determinant
	
	a = U1*Xi1 + U2*Yi1 + U3*Zi1
	b = 0
	c = U1*Xi2 + U2*Yi3 + U3*Zi3
	d = U1*Xi2 + U2*Yi2 + U3*Zi2

	e = V1*Xi1 + V2*Yi1 + V3*Zi1
	f = 0
	g = V1*Xi3 + V2*Yi3 + V3*Zi3
	h = V1*Xi2 + V2*Yi2 + V3*Zi2

  using similar equations for the case of constant X and Z, we can successfully
  convert XYZ coordinates to DfUV texture coordinates for about 97% of the 
  Arch3D objects.  This still leaves arounds 270 objects where the XYZ
  determinant is zero.  All remaining objects can be solved by the following
  rules:

	- Ignore faces with 4 or fewer points as the face contains the direct
	  UV information for the first 4 points.
	- Ignore faces with solid colors (textures 0 and 1).
	- If the above cases fail to find a valid solution, attempt the remaining
	  cases for a XZ, XY, and YZ solutions (one should work).  This is due
	  to some faces having similar/identical X/Z coordinates.
  	
  To convert from DfUV coordinates (computed above) into 'normal' UV, the
  following equations can be used:

	NU = (aX + bY + cZ + d) / (16 * TextureWidth)
	NV = (eX + fY + gZ + h) / (16 * TextureHeight)

  Normal UV coordinates are based on a value of 1.0 equaling the texture
  width or height and are usually used in 3D modelling programs.  These
  equations appear to give the correct texture coordinates for most 3D
  objects.


  Appendix F - LAND CREATION NOTES
====================================
  Steps to create a map 'block' or pixel.  The entire DF map is composed of 
  1000x500 land pixels, each of which is further divided into 5x5 subpixels as
  per the WOODS.WLD data.  Each pixel can contain only one town or dungeon and
  has a given terrain type, texture, and roughness.

    == All Pixels ==
	1. Generate land pixel from Woods.WLD
	2. Smooth edges with adajacent pixels
	3. Add flats to landscape (trees, bushes, rocks, etc...)
	4. Check for a location within the pixel.  Currently, the only known
	   way to do this is to check all the locations within the current
	   region.  It may be indicated by the first two bytes in a pixel
	   record in WOODS.WLD, but this is not yet confirmed
		A. Load just the maptable for the region, if not loaded
		B. Check all locations or a pixel-coordinate match
		C. Stop search on first match
    == Location Only Pixels ==
	5. Load entire location from MAPS.BSA
	6. Smooth appropiate land for location. How to get width/height for
	   location or just smooth entire pixel? Smoothing should not be
	   absolute, there should still be some random 'ripple'.  If the
 	   entire pixel is to be smoothed, this could be done in Step 1.
	6. Parse through the object list in the map record (post records)
	   	A. Load appropiate Blocks.BSA record.
		B. Parse Blocks.BSA record, create block D3D frame
			i.  Load Arch3D.BSA object
			ii. Add object to frame at required position
		C. Add block frame to land pixel frame at required position

	*


If you have any problems, suggestions or comments on this page or website, please feel free to use the Contact Form to send a message to the WebMaster.
This document was last modified on: Tuesday, 15 February 2011, at 20:25:32 and has been accessed 3111 times ( dagger/dfbsa.txt ).
/text.shtml