diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index 2be06e73a3..0e0e54bcdc 100644 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -13,6 +13,6 @@ namespace OpenRa.Game public float2 renderLocation; public int palette; public abstract Sprite[] CurrentImages { get; } - public abstract void Tick( World world, double t ); + public virtual void Tick(World world, double t) { } } } diff --git a/OpenRa.Game/Clock.cs b/OpenRa.Game/Clock.cs deleted file mode 100644 index 806ae14b2b..0000000000 --- a/OpenRa.Game/Clock.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; - -namespace OpenRa.Game -{ - public static class Clock - { - [DllImport("kernel32.dll")] - static extern bool QueryPerformanceCounter(out long value); - [DllImport("kernel32.dll")] - static extern bool QueryPerformanceFrequency(out long frequency); - - static int frameCount = 0; - static long frequency; - static long lastTime; - static double frameTime = 0; - static double totalTime = 0; - const int FramerateUpdateFrequency = 10; - static int lastFrameRate = 0; - static int lastFrameCount = 0; - static double nextFrameRateUpdateTime = 0; - - static Clock() - { - QueryPerformanceFrequency(out frequency); - QueryPerformanceCounter(out lastTime); - } - - public static void Reset() - { - totalTime = 0; - } - - public static void StartFrame() - { - long time; - QueryPerformanceCounter(out time); - - frameTime = (double)(time - lastTime) / (double)frequency; - totalTime += frameTime; - - lastTime = time; - - frameCount++; - - if (totalTime > nextFrameRateUpdateTime) - { - nextFrameRateUpdateTime += (1.0 / FramerateUpdateFrequency); - const int OldFramerateWeight = 20; - const int NewFramerateWeight = 1; - int newFrameRate = (frameCount - lastFrameCount) * FramerateUpdateFrequency; - lastFrameRate = (lastFrameRate * OldFramerateWeight + NewFramerateWeight * newFrameRate) - / (OldFramerateWeight + NewFramerateWeight); - lastFrameCount = frameCount; - } - } - - public static double Time - { - get { return totalTime; } - } - - public static int FrameRate - { - get { return lastFrameRate; } - } - - public static double FrameTime - { - get { return frameTime; } - } - } -} diff --git a/OpenRa.Game/ConstructionYard.cs b/OpenRa.Game/ConstructionYard.cs new file mode 100644 index 0000000000..92f81337d2 --- /dev/null +++ b/OpenRa.Game/ConstructionYard.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; +using BluntDirectX.Direct3D; + +namespace OpenRa.Game +{ + class ConstructionYard : Actor + { + static Range normalSequence = UnitSheetBuilder.GetUnit("fact"); + static Range makeSequence = UnitSheetBuilder.GetUnit("factmake"); + + Range sequence = makeSequence; + int frame = -1; + + public ConstructionYard(float2 location, int palette) + { + this.renderLocation = location; + this.palette = palette; + } + + public override Sprite[] CurrentImages + { + get + { + if ((sequence.Start == makeSequence.Start) && ++frame >= sequence.End - sequence.Start) + { + frame = 0; + sequence = normalSequence; + } + + return new Sprite[] { UnitSheetBuilder.sprites[sequence.Start + frame] }; + } + } + + public override void Tick(World world, double t) { } + } +} diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index ad926cf8e1..fd88c492fc 100644 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -60,17 +60,30 @@ namespace OpenRa.Game foreach (TreeReference treeReference in map.Trees) world.Add(new Tree(treeReference, treeCache, map)); + PrecacheStructure("proc"); + PrecacheStructure("fact"); + PrecacheUnit("mcv"); + world.Add(new Mcv(new int2(5, 5), 3)); world.Add(new Mcv(new int2(7, 5), 2)); Mcv mcv = new Mcv( new int2( 9, 5 ), 1 ); myUnit = mcv; world.Add( mcv ); - world.Add(new Refinery(24 * new float2(5, 7), 1)); - sidebar = new Sidebar(Race.Soviet, renderer, viewport); } + void PrecacheStructure(string name) + { + UnitSheetBuilder.GetUnit(name); + UnitSheetBuilder.GetUnit(name + "make"); + } + + void PrecacheUnit(string name) + { + UnitSheetBuilder.GetUnit(name); + } + internal void Run() { while (Created && Visible) diff --git a/OpenRa.Game/Mcv.cs b/OpenRa.Game/Mcv.cs index f4c96ed0ae..74c7e19145 100644 --- a/OpenRa.Game/Mcv.cs +++ b/OpenRa.Game/Mcv.cs @@ -9,7 +9,8 @@ namespace OpenRa.Game { class Mcv : Actor, ISelectable { - static Range? mcvRange = null; + static Range mcvRange = UnitSheetBuilder.GetUnit("mcv"); + int facing = 0; int2 fromCell, toCell; int moveFraction, moveFractionTotal; @@ -18,28 +19,16 @@ namespace OpenRa.Game TickFunc currentOrder = null; TickFunc nextOrder = null; - public Mcv( int2 cell, int palette ) + public Mcv(int2 cell, int palette) { fromCell = toCell = cell; - float2 location = ( cell * 24 ).ToFloat2(); - this.renderLocation = location - new float2( 12, 12 ); // HACK: display the mcv centered in it's cell + // HACK: display the mcv centered in it's cell; + renderLocation = (cell * 24).ToFloat2() - new float2(12, 12); this.palette = palette; - - if (mcvRange == null) - mcvRange = UnitSheetBuilder.AddUnit("mcv"); } - static float2[] fvecs; - - static Mcv() - { - fvecs = new float2[32]; - for (int i = 0; i < 32; i++) - { - float angle = i / 16.0f * (float)Math.PI; - fvecs[i] = new float2(-(float)Math.Sin(angle), -(float)Math.Cos(angle)); - } - } + static float2[] fvecs = Util.MakeArray(32, + delegate(int i) { return -float2.FromAngle(i / 16.0f * (float)Math.PI); }); int GetFacing(float2 d) { @@ -49,7 +38,7 @@ namespace OpenRa.Game int highest = -1; float highestDot = -1.0f; - for (int i = 0; i < 32; i++) + for (int i = 0; i < fvecs.Length; i++) { float dot = float2.Dot(fvecs[i], d); if (dot > highestDot) @@ -64,10 +53,7 @@ namespace OpenRa.Game public override Sprite[] CurrentImages { - get - { - return new Sprite[] { UnitSheetBuilder.sprites[facing + mcvRange.Value.Start] }; - } + get { return new Sprite[] { UnitSheetBuilder.sprites[facing + mcvRange.Start] }; } } const int Speed = 6; @@ -95,13 +81,7 @@ namespace OpenRa.Game int desiredFacing = GetFacing( ( toCell - fromCell ).ToFloat2() ); if( facing != desiredFacing ) - { - int df = ( desiredFacing - facing + 32 ) % 32; - if( df > 16 ) - facing = ( facing + 31 ) % 32; - else - facing = ( facing + 1 ) % 32; - } + Turn(desiredFacing); else { moveFraction += speed; @@ -112,13 +92,11 @@ namespace OpenRa.Game fromCell = toCell; if( toCell == destination ) - { currentOrder = null; - } else { int2 dir = destination - fromCell; - toCell = fromCell + new int2( Math.Sign( dir.X ), Math.Sign( dir.Y ) ); + toCell = fromCell + dir.Sign(); moveFractionTotal = ( dir.X != 0 && dir.Y != 0 ) ? 250 : 200; } } @@ -126,39 +104,36 @@ namespace OpenRa.Game float2 location; if( moveFraction > 0 ) - { - float frac = (float)moveFraction / moveFractionTotal; - location = 24 * ( ( 1 - frac ) * fromCell.ToFloat2() + frac * toCell.ToFloat2() ); - } + location = 24 * float2.Lerp(fromCell.ToFloat2(), toCell.ToFloat2(), + (float)moveFraction / moveFractionTotal); else location = 24 * fromCell.ToFloat2(); renderLocation = location - new float2( 12, 12 ); // HACK: center mcv in it's cell - renderLocation.X = (float)Math.Round( renderLocation.X ); - renderLocation.Y = (float)Math.Round( renderLocation.Y ); + renderLocation = renderLocation.Round(); }; } + void Turn(int desiredFacing) + { + int df = (desiredFacing - facing + 32) % 32; + facing = (facing + (df > 16 ? 31 : 1)) % 32; + } + public void AcceptDeployOrder() { nextOrder = delegate( World world, double t ) { int desiredFacing = 12; - if( facing != desiredFacing ) - { - int df = ( desiredFacing - facing + 32 ) % 32; - if( df > 16 ) - facing = ( facing + 31 ) % 32; - else - facing = ( facing + 1 ) % 32; - } + if (facing != desiredFacing) + Turn(desiredFacing); else { - world.AddFrameEndTask( delegate + world.AddFrameEndTask(delegate { - world.Add( new Refinery( ( fromCell * 24 - new int2( 24, 24 ) ).ToFloat2(), palette ) ); - } ); + world.Add(new ConstructionYard((fromCell * 24 - new int2(24, 24)).ToFloat2(), palette)); + }); currentOrder = null; } }; diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 5f1204f2ef..f79e7c6839 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -41,7 +41,7 @@ - + diff --git a/OpenRa.Game/Refinery.cs b/OpenRa.Game/Refinery.cs index 52845edaee..d8529f6442 100644 --- a/OpenRa.Game/Refinery.cs +++ b/OpenRa.Game/Refinery.cs @@ -9,13 +9,10 @@ namespace OpenRa.Game { class Refinery : Actor { - static Range? refineryRange = null; + static Range sequence = UnitSheetBuilder.GetUnit("proc"); public Refinery(float2 location, int palette) { - if (refineryRange == null) - refineryRange = UnitSheetBuilder.AddUnit("proc"); - this.renderLocation = location; this.palette = palette; } @@ -26,10 +23,8 @@ namespace OpenRa.Game { get { - return new Sprite[] { UnitSheetBuilder.sprites[refineryRange.Value.Start + GetFrame()] }; + return new Sprite[] { UnitSheetBuilder.sprites[sequence.Start + GetFrame()] }; } } - - public override void Tick( World world, double t ) { } } } diff --git a/OpenRa.Game/Settings.cs b/OpenRa.Game/Settings.cs index 720eddb564..512f859ff0 100644 --- a/OpenRa.Game/Settings.cs +++ b/OpenRa.Game/Settings.cs @@ -22,15 +22,9 @@ namespace OpenRa.Game } } - public bool Contains(string key) - { - return settings.ContainsKey(key); - } + public bool Contains(string key) { return settings.ContainsKey(key); } - public string GetValue(string key, string defaultValue) - { - return Contains(key) ? settings[key] : defaultValue; - } + public string GetValue(string key, string defaultValue) { return Contains(key) ? settings[key] : defaultValue; } public int GetValue(string key, int defaultValue) { diff --git a/OpenRa.Game/Tree.cs b/OpenRa.Game/Tree.cs index ba134b8ccd..1938d0efd5 100644 --- a/OpenRa.Game/Tree.cs +++ b/OpenRa.Game/Tree.cs @@ -15,11 +15,7 @@ namespace OpenRa.Game } Sprite[] currentImages; - public override Sprite[] CurrentImages - { - get { return currentImages; } - } - public override void Tick( World world, double t ) { } + public override Sprite[] CurrentImages { get { return currentImages; } } } } diff --git a/OpenRa.Game/UnitSheetBuilder.cs b/OpenRa.Game/UnitSheetBuilder.cs index e8c39d5319..2d6034f9f1 100644 --- a/OpenRa.Game/UnitSheetBuilder.cs +++ b/OpenRa.Game/UnitSheetBuilder.cs @@ -14,6 +14,8 @@ namespace OpenRa.Game public static readonly List sprites = new List(); + static Dictionary> sequences = new Dictionary>(); + static ShpReader Load(string filename) { foreach( Package p in new Package[] { unitsPackage, otherUnitsPackage } ) @@ -23,14 +25,25 @@ namespace OpenRa.Game throw new NotImplementedException(); } - public static Range AddUnit( string name ) + public static Range GetUnit(string name) + { + Range result; + if (sequences.TryGetValue(name, out result)) + return result; + + return AddUnit(name); + } + + static Range AddUnit( string name ) { int low = sprites.Count; ShpReader reader = Load(name + ".shp"); foreach (ImageHeader h in reader) sprites.Add(SheetBuilder.Add(h.Image, reader.Size)); - return new Range(low, sprites.Count - 1); + Range sequence = new Range(low, sprites.Count - 1); + sequences.Add(name, sequence); + return sequence; } } } diff --git a/OpenRa.Game/Util.cs b/OpenRa.Game/Util.cs index 8c0165d371..88ee729b68 100644 --- a/OpenRa.Game/Util.cs +++ b/OpenRa.Game/Util.cs @@ -35,7 +35,7 @@ namespace OpenRa.Game public static Vertex MakeVertex(float2 o, float2 uv, Sprite r, int palette) { return new Vertex( - Lerp( o, o + new float2(r.bounds.Size), uv ), + float2.Lerp( o, o + new float2(r.bounds.Size), uv ), r.MapTextureCoords(uv), EncodeVertexAttributes(r.channel, palette)); } @@ -45,11 +45,13 @@ namespace OpenRa.Game return (1 - t) * a + t * b; } - static float2 Lerp(float2 a, float2 b, float2 t) + public static T[] MakeArray(int count, Converter f) { - return new float2( - Lerp(a.X, b.X, t.X), - Lerp(a.Y, b.Y, t.Y)); + T[] result = new T[count]; + for (int i = 0; i < count; i++) + result[i] = f(i); + + return result; } static float2[] uv = diff --git a/OpenRa.Game/float2.cs b/OpenRa.Game/float2.cs index 99096c3ac7..d08839a298 100644 --- a/OpenRa.Game/float2.cs +++ b/OpenRa.Game/float2.cs @@ -20,14 +20,30 @@ namespace OpenRa.Game public PointF ToPointF() { return new PointF(X, Y); } - public static float2 operator +(float2 a, float2 b) + public static float2 operator +(float2 a, float2 b) { return new float2(a.X + b.X, a.Y + b.Y); } + public static float2 operator -(float2 a, float2 b) { return new float2(a.X - b.X, a.Y - b.Y); } + + public static float2 operator -(float2 a) { return new float2(-a.X, -a.Y); } + + static float Lerp(float a, float b, float t) { return (1 - t) * a + t * b; } + + public static float2 Lerp(float2 a, float2 b, float t) { - return new float2(a.X + b.X, a.Y + b.Y); + return new float2( + Lerp(a.X, b.X, t), + Lerp(a.Y, b.Y, t)); } - public static float2 operator -(float2 a, float2 b) + public static float2 Lerp(float2 a, float2 b, float2 t) { - return new float2(a.X - b.X, a.Y - b.Y); + return new float2( + Lerp(a.X, b.X, t.X), + Lerp(a.Y, b.Y, t.Y)); + } + + public static float2 FromAngle(float a) + { + return new float2((float)Math.Sin(a), (float)Math.Cos(a)); } public float2 Constrain(Range r) @@ -55,21 +71,8 @@ namespace OpenRa.Game return Math.Abs(d.X) < e && Math.Abs(d.Y) < e; } - static float Sign(float f) - { - if (f > 0) return 1; - if (f < 0) return -1; - return 0; - } - - public float2 Sign() - { - return new float2(Sign(X), Sign(Y)); - } - - public static float Dot(float2 a, float2 b) - { - return a.X * b.X + a.Y * b.Y; - } + public float2 Sign() { return new float2(Math.Sign(X), Math.Sign(Y)); } + public static float Dot(float2 a, float2 b) { return a.X * b.X + a.Y * b.Y; } + public float2 Round() { return new float2((float)Math.Round(X), (float)Math.Round(Y)); } } } diff --git a/OpenRa.Game/int2.cs b/OpenRa.Game/int2.cs index 7363a1adf0..a87c2479bb 100644 --- a/OpenRa.Game/int2.cs +++ b/OpenRa.Game/int2.cs @@ -7,45 +7,32 @@ namespace OpenRa.Game { struct int2 { - public int X; - public int Y; + public int X,Y; public int2( int x, int y ) { this.X = x; this.Y = y; } public int2( Point p ) { X = p.X; Y = p.Y; } public int2( Size p ) { X = p.Width; Y = p.Height; } - public static int2 operator +( int2 a, int2 b ) - { - return new int2( a.X + b.X, a.Y + b.Y ); - } + public static int2 operator +(int2 a, int2 b) { return new int2(a.X + b.X, a.Y + b.Y); } + public static int2 operator -(int2 a, int2 b) { return new int2(a.X - b.X, a.Y - b.Y); } + public static int2 operator *(int a, int2 b) { return new int2(a * b.X, a * b.Y); } + public static int2 operator *(int2 b, int a) { return new int2(a * b.X, a * b.Y); } - public static int2 operator -( int2 a, int2 b ) - { - return new int2( a.X - b.X, a.Y - b.Y ); - } + public float2 ToFloat2() { return new float2(X, Y); } - public static int2 operator *( int a, int2 b ) - { - return new int2( a * b.X, a * b.Y ); - } - public static int2 operator *( int2 b, int a ) - { - return new int2( a * b.X, a * b.Y ); - } + public static bool operator ==(int2 me, int2 other) { return (me.X == other.X && me.Y == other.Y); } + public static bool operator !=(int2 me, int2 other) { return !(me == other); } - public float2 ToFloat2() - { - return new float2( X, Y ); - } + public int2 Sign() { return new int2(Math.Sign(X), Math.Sign(Y)); } + public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode(); } - public static bool operator ==( int2 me, int2 other ) + public override bool Equals(object obj) { - return ( me.X == other.X && me.Y == other.Y ); - } + if (obj == null) + return false; - public static bool operator !=( int2 me, int2 other ) - { - return !( me == other ); + int2 o = (int2)obj; + return o == this; } -} + } }