I found a way to read and write new treasure map graphics - facet0*.mul.
Maybe my code isn't very fast but it works:)
Code: Select all
/// <summary>
/// Reads facet0x.mul
/// </summary>
/// <returns>image of map</returns>
public Bitmap GetFacetImage()
{
Bitmap bmp;
using ( BinaryReader reader = new BinaryReader( new FileStream( Files.GetFilePath( String.Format( "facet0{0}.mul", m_FileIndex ) ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) )
{
int width = reader.ReadInt16();
int height = reader.ReadInt16();
bmp = new Bitmap( width, height );
int totalCount = 0;
Graphics g = Graphics.FromImage( bmp );
for ( int y = 0; y < height; y++ )
{
int colorsCount = reader.ReadInt32() / 3;
for ( int c = 0; c < colorsCount; c++ )
{
byte count = reader.ReadByte();
short color = reader.ReadInt16();
g.FillRectangle( new SolidBrush( Hues.HueToColor( color ) ), totalCount, y, count, 1 );
totalCount += count;
}
totalCount = 0;
}
g.Dispose();
}
return bmp;
}
Code: Select all
public static void SaveFacetImage( int mapID, Bitmap sourceBitmap )
{
int width = sourceBitmap.Width;
int height = sourceBitmap.Height;
using( BinaryWriter writer = new BinaryWriter( new FileStream( String.Format( "facet0{0}.mul", mapID ), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite ) ) )
{
writer.Write( (short)width );
writer.Write( (short)height );
for( int y = 0; y < height; y++ )
{
writer.Write( 0 );//bytes count for current line
int colorsAtLine = 0;
int colorsCount = 0;
int x = 0;
while ( x < width )
{
short hue = ColorToHue( sourceBitmap.GetPixel( x, y ) );
while ( x < width && colorsCount < byte.MaxValue && hue == ColorToHue( sourceBitmap.GetPixel( x, y ) ) )
{
colorsCount++;
x++;
}
short h = hue;
writer.Write( ( byte )colorsCount );
writer.Write( h );
colorsAtLine++;
colorsCount = 0;
}
long offset = ( colorsAtLine * -3 );
writer.BaseStream.Seek( offset - 4, SeekOrigin.Current );
writer.Write( colorsAtLine *3 );//bytes count for current line
writer.BaseStream.Seek( Math.Abs( offset ), SeekOrigin.Current );
}
}
}