RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

How are maps stored?

Tissemand

Squire
In the most basic sense, how are maps stored for UO?
I'm trying to write a program to render maps using C, and UltimaSDK is way out of my head to even concentrate on.
 

Tissemand

Squire
Am I doing this correctly (sorta pseudocoded in C#)?
Code:
            BinaryReader reader = new BinaryReader(File.Open(@"\Program Files (x86)\EA Games\Ultima Online 2D Client\map0.mul", FileMode.Open));

            while (reader.BaseStream.CanRead)
            {
                Block block;
                block.header = reader.ReadInt32();
                block.cells = new Cell[8,8];
                for( int i = 0; i < 8; i++ )
                {
                    for ( int j = 0; j < 8; j++ )
                    {
                        block.cells[i, j].tileId = reader.ReadInt16();
                        block.cells[i, j].z = reader.ReadSByte();
                    }
                }
            }
            reader.Close();

Then to get the image, I should just search up each block tile id's on the land art?
 

Jeff

Lord
Block:
int header; // Unknown
Cells...
Each block contains 64 cells, treated as an 8x8 matrix loaded left to right, top to bottom.
so
Code:
for(int x = 0; x < 8; x++)
for(int y = 0; y < 8; y++)
{
    int cellX = x;
    int cellY = y;
}

EDIT: You had that code already
Code:
                for( int i = 0; i < 8; i++ )
                {
                    for ( int j = 0; j < 8; j++ )
                    {
                        block.cells[i, j].tileId = reader.ReadInt16();
                        block.cells[i, j].z = reader.ReadSByte();
                    }
                }
 

Tissemand

Squire
so
Code:
for(int x = 0; x < 8; x++)
for(int y = 0; y < 8; y++)
{
    int cellX = x;
    int cellY = y;
}

EDIT: You had that code already
Code:
                for( int i = 0; i < 8; i++ )
                {
                    for ( int j = 0; j < 8; j++ )
                    {
                        block.cells[i, j].tileId = reader.ReadInt16();
                        block.cells[i, j].z = reader.ReadSByte();
                    }
                }
Bah, I meant, if I have the character's coords, (and I fseek to the proper block) how can I get the position in the block?
 

Jeff

Lord
To get the block they are on, take player x,y and divide by 8.
To get the cell within the block, take player x,y modulus of 8.
 

Tissemand

Squire
There seems to be something odd happening:

I tried seeking to 123x123, and it gave me item ids ranging from 3-6, with z's of 0.
Do you see anything that's wrong by chance? :confused:

maps.c
Code:
Block getBlock( FILE * file, uint32_t x, uint32_t y, uint32_t block_height )
{
  long filePos = ((x * block_height) + y) * 196;
  Block block;

  fseek( file, filePos, SEEK_SET );
  getNextBlock( file, &block );

  return block;
}

void getNextBlock( FILE * mapFile, Block * block )
{
  int i, j;
  //Block block;

  // read 32 bits
  fread( &(block->header), sizeof(int32_t), 1, mapFile );

  // loop through to fill the 8x8 matrix
  for( i = 0; i < 8; i++ )
  {
    for( j = 0; j < 8; j++ )
    {
      // read 16 bits, and use htons to fix endian issue
      int16_t tile;
      fread( &tile, sizeof(int16_t), 1, mapFile );
      (block->cells[i][j].tileId) = htons( tile );

      // read 8 bits
      fread( &(block->cells[i][j].z), sizeof(int8_t), 1, mapFile );
    }
  }
}

main.c
Code:
      Block block = getBlock( mapFile, 123, 123, 512 );
      int i, j;
      for( i = 0; i < 8; i++ )
      {
        for( j = 0; j < 8; j++ )
        {
          printf( "%i %i", block.cells[i][j].tileId, block.cells[i][j].z );
        }
      }
 
Top