From f87448c95864825392154c6ecfb6aae1ee6ebf98 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 26 Jun 2007 12:40:42 +0000 Subject: [PATCH] git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1080 993157c7-ee19-0410-b2c4-bb4e9862e678 --- MapViewer/IniFile.cs | 88 -------------- MapViewer/MapViewer.csproj | 1 - MapViewer/Program.cs | 87 ++------------ OpenRa.FileFormats/IniFile.cs | 87 ++++++++++++++ OpenRa.FileFormats/Map.cs | 117 +++++++++++++++++++ OpenRa.FileFormats/OpenRa.FileFormats.csproj | 2 + 6 files changed, 216 insertions(+), 166 deletions(-) delete mode 100644 MapViewer/IniFile.cs create mode 100644 OpenRa.FileFormats/IniFile.cs create mode 100644 OpenRa.FileFormats/Map.cs diff --git a/MapViewer/IniFile.cs b/MapViewer/IniFile.cs deleted file mode 100644 index 8161af4f40..0000000000 --- a/MapViewer/IniFile.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Text.RegularExpressions; - -namespace MapViewer -{ - class IniFile - { - Dictionary sections = new Dictionary(); - IniSection currentSection; - - public IniFile(Stream s) - { - - StreamReader reader = new StreamReader(s); - while (!reader.EndOfStream) - { - string line = reader.ReadLine(); - if (!ProcessEntry(line)) - ProcessSection(line); - } - } - - Regex sectionPattern = new Regex(@"\[([^]]*)\]"); - Regex entryPattern = new Regex(@"([^=]+)=([^;]*)"); - - bool ProcessSection(string line) - { - Match m = sectionPattern.Match(line); - if (m == null || !m.Success) - return false; - - string sectionName = m.Groups[1].Value; - currentSection = new IniSection(sectionName); - sections.Add(sectionName, currentSection); - - return true; - } - - bool ProcessEntry(string line) - { - Match m = entryPattern.Match(line); - if (m == null || !m.Success) - return false; - - if (currentSection == null) - throw new InvalidOperationException("No current INI section"); - - string keyName = m.Groups[1].Value; - string keyValue = m.Groups[2].Value; - - currentSection.Add(keyName, keyValue); - - return true; - } - - public IniSection GetSection(string s) - { - IniSection section; - sections.TryGetValue(s, out section); - return section; - } - } - - class IniSection - { - string name; - Dictionary values = new Dictionary(); - - public IniSection(string name) - { - this.name = name; - } - - public void Add(string key, string value) - { - values.Add(key, value); - } - - public string GetValue(string key, string defaultValue) - { - string s; - return values.TryGetValue( key, out s ) ? s : defaultValue; - } - } -} diff --git a/MapViewer/MapViewer.csproj b/MapViewer/MapViewer.csproj index e7b51c2096..32af505b89 100644 --- a/MapViewer/MapViewer.csproj +++ b/MapViewer/MapViewer.csproj @@ -35,7 +35,6 @@ - diff --git a/MapViewer/Program.cs b/MapViewer/Program.cs index ee57870fbf..fec4f54a55 100644 --- a/MapViewer/Program.cs +++ b/MapViewer/Program.cs @@ -13,7 +13,7 @@ namespace MapViewer { OpenFileDialog ofd = new OpenFileDialog(); ofd.RestoreDirectory = true; - ofd.Filter = "Map files (*.ini)|*.ini"; + ofd.Filter = "Map files (*.ini;*.mpr)|*.ini;*.mpr"; return (DialogResult.OK == ofd.ShowDialog()) ? ofd.OpenFile() : null; } @@ -38,86 +38,19 @@ namespace MapViewer IniFile iniFile = new IniFile(s); Console.WriteLine("Done."); - IniSection basic = iniFile.GetSection("Basic"); - Console.WriteLine("Name: {0}", basic.GetValue("Name", "(null)")); - Console.WriteLine("Official: {0}", basic.GetValue("Official", "no")); + Map map = new Map( iniFile ); - IniSection map = iniFile.GetSection("Map"); - Console.WriteLine("Theater: {0}", map.GetValue("Theater", "TEMPERATE")); - Console.WriteLine("X: {0} Y: {1} Width: {2} Height: {3}", - map.GetValue("X", "0"), map.GetValue("Y", "0"), - map.GetValue("Width", "0"), map.GetValue("Height", "0")); + Console.WriteLine( "Name: {0}", map.Title ); - int width = int.Parse(map.GetValue("Width", "0")); - int height = int.Parse(map.GetValue("Height", "0")); + IniSection basic = iniFile.GetSection( "Basic" ); + Console.WriteLine( "Official: {0}", basic.GetValue( "Official", "no" ) ); - int x = int.Parse(map.GetValue("X", "0")); - int y = int.Parse(map.GetValue("Y", "0")); + Console.WriteLine( "Theater: {0}", map.Theater ); + Console.WriteLine( "X: {0} Y: {1} Width: {2} Height: {3}", + map.XOffset, map.YOffset, map.Width, map.Height ); - // parse MapPack section - IniSection mapPackSection = iniFile.GetSection("MapPack"); - - StringBuilder sb = new StringBuilder(); - for (int i = 1; ; i++) - { - string line = mapPackSection.GetValue(i.ToString(), null); - if (line == null) - break; - - sb.Append(line.Trim()); - } - - byte[] data = Convert.FromBase64String(sb.ToString()); - Console.WriteLine("Format80 data: {0}", data.Length); - - List chunks = new List(); - - BinaryReader reader = new BinaryReader(new MemoryStream(data)); - - try - { - while (true) - { - uint length = reader.ReadUInt32() & 0xdfffffff; - byte[] dest = new byte[8192]; - byte[] src = reader.ReadBytes((int)length); - - int actualLength = Format80.DecodeInto(new MemoryStream(src), dest); - - chunks.Add(dest); - Console.WriteLine("Chunk length: {0}", actualLength); - } - } - catch (EndOfStreamException) { } - - MemoryStream ms = new MemoryStream(); - foreach (byte[] chunk in chunks) - ms.Write(chunk, 0, chunk.Length); - - ms.Position = 0; - - TileReference[ , ] tiles = new TileReference[ 128, 128 ]; - for( int i = 0 ; i < 128 ; i++ ) - { - for( int j = 0 ; j < 128 ; j++ ) - { - tiles[ i, j ].tile = ReadByte( ms ); - tiles[ i, j ].tile |= (ushort)( ReadByte( ms ) << 8 ); - } - } - - for( int i = 0 ; i < 128 ; i++ ) - for( int j = 0 ; j < 128 ; j++ ) - tiles[ i, j ].image = ReadByte( ms ); - - foreach( TileReference r in tiles ) - Console.Write( "{0:x4}.{1:x2} ", r.tile, r.image ); + foreach( TileReference r in map.MapTiles ) + Console.WriteLine( "{0:x4}.{1:x2} ", r.tile, r.image ); } } - - struct TileReference - { - public ushort tile; - public byte image; - } } diff --git a/OpenRa.FileFormats/IniFile.cs b/OpenRa.FileFormats/IniFile.cs new file mode 100644 index 0000000000..0f94d30660 --- /dev/null +++ b/OpenRa.FileFormats/IniFile.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Text.RegularExpressions; + +namespace MapViewer +{ + public class IniFile + { + Dictionary sections = new Dictionary(); + IniSection currentSection; + + public IniFile( Stream s ) + { + StreamReader reader = new StreamReader( s ); + while( !reader.EndOfStream ) + { + string line = reader.ReadLine(); + if( !ProcessEntry( line ) ) + ProcessSection( line ); + } + } + + Regex sectionPattern = new Regex( @"\[([^]]*)\]" ); + Regex entryPattern = new Regex( @"([^=]+)=([^;]*)" ); + + bool ProcessSection( string line ) + { + Match m = sectionPattern.Match( line ); + if( m == null || !m.Success ) + return false; + + string sectionName = m.Groups[ 1 ].Value; + currentSection = new IniSection( sectionName ); + sections.Add( sectionName, currentSection ); + + return true; + } + + bool ProcessEntry( string line ) + { + Match m = entryPattern.Match( line ); + if( m == null || !m.Success ) + return false; + + if( currentSection == null ) + throw new InvalidOperationException( "No current INI section" ); + + string keyName = m.Groups[ 1 ].Value; + string keyValue = m.Groups[ 2 ].Value; + + currentSection.Add( keyName, keyValue ); + + return true; + } + + public IniSection GetSection( string s ) + { + IniSection section; + sections.TryGetValue( s, out section ); + return section; + } + } + + public class IniSection + { + string name; + Dictionary values = new Dictionary(); + + public IniSection( string name ) + { + this.name = name; + } + + public void Add( string key, string value ) + { + values.Add( key, value ); + } + + public string GetValue( string key, string defaultValue ) + { + string s; + return values.TryGetValue( key, out s ) ? s : defaultValue; + } + } +} diff --git a/OpenRa.FileFormats/Map.cs b/OpenRa.FileFormats/Map.cs new file mode 100644 index 0000000000..1c303f7861 --- /dev/null +++ b/OpenRa.FileFormats/Map.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using MapViewer; + +namespace OpenRa.FileFormats +{ + public class Map + { + public readonly string Title; + public readonly string Theater; + + public readonly int XOffset; + public readonly int YOffset; + + public readonly int Width; + public readonly int Height; + + public readonly TileReference[ , ] MapTiles = new TileReference[ 128, 128 ]; + + public Map( IniFile file ) + { + IniSection basic = file.GetSection( "Basic" ); + Title = basic.GetValue( "Name", "(null)" ); + + IniSection map = file.GetSection( "Map" ); + Theater = map.GetValue( "Theater", "TEMPERATE" ); + + XOffset = int.Parse( map.GetValue( "X", "0" ) ); + YOffset = int.Parse( map.GetValue( "Y", "0" ) ); + + Width = int.Parse( map.GetValue( "Width", "0" ) ); + Height = int.Parse( map.GetValue( "Height", "0" ) ); + + MemoryStream ms = ReadMapPack( file ); + + UnpackTileData( ms ); + } + + static MemoryStream ReadMapPack( IniFile file ) + { + IniSection mapPackSection = file.GetSection( "MapPack" ); + + StringBuilder sb = new StringBuilder(); + for( int i = 1 ; ; i++ ) + { + string line = mapPackSection.GetValue( i.ToString(), null ); + if( line == null ) + break; + + sb.Append( line.Trim() ); + } + + byte[] data = Convert.FromBase64String( sb.ToString() ); + Console.WriteLine( "Format80 data: {0}", data.Length ); + + List chunks = new List(); + + BinaryReader reader = new BinaryReader( new MemoryStream( data ) ); + + try + { + while( true ) + { + uint length = reader.ReadUInt32() & 0xdfffffff; + byte[] dest = new byte[ 8192 ]; + byte[] src = reader.ReadBytes( (int)length ); + + int actualLength = Format80.DecodeInto( new MemoryStream( src ), dest ); + + chunks.Add( dest ); + Console.WriteLine( "Chunk length: {0}", actualLength ); + } + } + catch( EndOfStreamException ) { } + + MemoryStream ms = new MemoryStream(); + foreach( byte[] chunk in chunks ) + ms.Write( chunk, 0, chunk.Length ); + + ms.Position = 0; + + return ms; + } + + static byte ReadByte( Stream s ) + { + int ret = s.ReadByte(); + if( ret == -1 ) + throw new NotImplementedException(); + return (byte)ret; + } + + void UnpackTileData( MemoryStream ms ) + { + for( int i = 0 ; i < 128 ; i++ ) + { + for( int j = 0 ; j < 128 ; j++ ) + { + MapTiles[ i, j ].tile = ReadByte( ms ); + MapTiles[ i, j ].tile |= (ushort)( ReadByte( ms ) << 8 ); + } + } + + for( int i = 0 ; i < 128 ; i++ ) + for( int j = 0 ; j < 128 ; j++ ) + MapTiles[ i, j ].image = ReadByte( ms ); + } + } + + public struct TileReference + { + public ushort tile; + public byte image; + } +} diff --git a/OpenRa.FileFormats/OpenRa.FileFormats.csproj b/OpenRa.FileFormats/OpenRa.FileFormats.csproj index bf8204c2d8..7885bed5b8 100644 --- a/OpenRa.FileFormats/OpenRa.FileFormats.csproj +++ b/OpenRa.FileFormats/OpenRa.FileFormats.csproj @@ -42,6 +42,8 @@ + +