diff --git a/ClassicalSharp.sln b/ClassicalSharp.sln
index f812403c2..06c6fef8c 100644
--- a/ClassicalSharp.sln
+++ b/ClassicalSharp.sln
@@ -1,6 +1,6 @@
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
# SharpDevelop 4.4
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassicalSharp", "ClassicalSharp\ClassicalSharp.csproj", "{BEB1C785-5CAD-48FF-A886-876BF0A318D4}"
EndProject
diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index 5750af17b..93eb1b6f4 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -33,8 +33,8 @@
False
DEBUG;TRACE
Project
- wwwf null 127.0.0.1 25566
obj\
+ wwwf null 127.0.0.1 25566
..\output\release\
@@ -129,7 +129,6 @@
-
@@ -156,6 +155,8 @@
+
+
@@ -187,6 +188,7 @@
+
diff --git a/ClassicalSharp/Commands/CommandManager.cs b/ClassicalSharp/Commands/CommandManager.cs
index e0b0f07c2..b5698774e 100644
--- a/ClassicalSharp/Commands/CommandManager.cs
+++ b/ClassicalSharp/Commands/CommandManager.cs
@@ -23,7 +23,7 @@ namespace ClassicalSharp.Commands {
RegisterCommand( new ViewDistanceCommand() );
}
- void RegisterCommand( Command command ) {
+ public void RegisterCommand( Command command ) {
command.Window = Window;
foreach( Command cmd in RegisteredCommands ) {
if( Utils.CaselessEquals( cmd.Name, command.Name ) ) {
diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs
index 16a4b0e7d..c48cc6d1b 100644
--- a/ClassicalSharp/Game/Game.cs
+++ b/ClassicalSharp/Game/Game.cs
@@ -139,7 +139,11 @@ namespace ClassicalSharp {
MapRenderer = new MapRenderer( this );
MapEnvRenderer = new MapEnvRenderer( this );
EnvRenderer = new StandardEnvRenderer( this );
- Network = new NetworkProcessor( this );
+ if( IPAddress == null ) {
+ Network = new Singleplayer.SinglePlayerServer( this );
+ } else {
+ Network = new NetworkProcessor( this );
+ }
firstPersonCam = new FirstPersonCamera( this );
thirdPersonCam = new ThirdPersonCamera( this );
Camera = firstPersonCam;
diff --git a/ClassicalSharp/Program.cs b/ClassicalSharp/Program.cs
index f78bc48cb..38ac9d72e 100644
--- a/ClassicalSharp/Program.cs
+++ b/ClassicalSharp/Program.cs
@@ -18,31 +18,41 @@ namespace ClassicalSharp {
if( !AllResourcesExist( "terrain.png", "char.png", "clouds.png" ) ) {
return;
}
- if( args.Length < 4 ) {
+ if( args.Length == 0 ) {
+ Utils.Log( "Starting singleplayer mode." );
+ using( Game game = new Game() ) {
+ game.Username = "LocalPlayer";
+ game.skinServer = "http://s3.amazonaws.com/MinecraftSkins/";
+ game.Run();
+ }
+ } else if( args.Length < 4 ) {
Fail( "ClassicalSharp.exe is only the raw client. You must either use the launcher or"
+ " provide command line arguments to start the client." );
- return;
+ } else {
+ RunMultiplayer( args );
+ }
+ }
+
+ static void RunMultiplayer( string[] args ) {
+ IPAddress ip = null;
+ if( !IPAddress.TryParse( args[2], out ip ) ) {
+ Fail( "Invalid IP \"" + args[2] + '"' );
}
- IPAddress ip = null;
- if( !IPAddress.TryParse( args[2], out ip ) ) {
- Fail( "Invalid IP \"" + args[2] + '"' );
- }
+ int port = 0;
+ if( !Int32.TryParse( args[3], out port ) ) {
+ Fail( "Invalid port \"" + args[3] + '"' );
+ return;
+ } else if( port < ushort.MinValue || port > ushort.MaxValue ) {
+ Fail( "Specified port " + port + " is out of valid range." );
+ }
- int port = 0;
- if( !Int32.TryParse( args[3], out port ) ) {
- Fail( "Invalid port \"" + args[3] + '"' );
- return;
- } else if( port < ushort.MinValue || port > ushort.MaxValue ) {
- Fail( "Specified port " + port + " is out of valid range." );
- }
-
- string skinServer = args.Length >= 5 ? args[4] : "http://s3.amazonaws.com/MinecraftSkins/";
+ string skinServer = args.Length >= 5 ? args[4] : "http://s3.amazonaws.com/MinecraftSkins/";
using( Game game = new Game() ) {
game.Username = args[0];
game.Mppass = args[1];
game.IPAddress = ip;
- game.Port = port;
+ game.Port = port;
game.skinServer = skinServer;
game.Run();
}
@@ -87,7 +97,7 @@ namespace ClassicalSharp {
"(and the circumstances that caused it) to github.com/UnknownShadow200/ClassicalSharp/issues" +
Environment.NewLine + Environment.NewLine + error;
- MessageBox.Show( "Oh dear. ClassicalSharp has crashed." + Environment.NewLine + Environment.NewLine + message, "ClassicalSharp has crashed" );
+ MessageBox.Show( "Oh dear. ClassicalSharp has crashed." + Environment.NewLine + Environment.NewLine + message, "ClassicalSharp has crashed" );
Environment.Exit( 1 );
}
}
diff --git a/ClassicalSharp/Singleplayer/Commands.cs b/ClassicalSharp/Singleplayer/Commands.cs
new file mode 100644
index 000000000..d6751565c
--- /dev/null
+++ b/ClassicalSharp/Singleplayer/Commands.cs
@@ -0,0 +1,43 @@
+using System;
+using ClassicalSharp.Commands;
+
+namespace ClassicalSharp.Singleplayer {
+
+ /// Command that modifies the font size of chat in the normal gui screen.
+ public sealed class GenerateCommand : Command {
+
+ public GenerateCommand() {
+ Name = "Generate";
+ Help = new [] {
+ "&a/client generate [width height length]",
+ "&bwidth: &eSpecifies X-axis/width of the new map.",
+ "&bheight: &eSpecifies Y-axis/height of the new map.",
+ "&blength: &eSpecifies Z-axis/length of the new map.",
+ };
+ }
+
+ public override void Execute( CommandReader reader ) {
+ int width, height, length;
+ if( !reader.NextInt( out width ) || !reader.NextInt( out height ) || !reader.NextInt( out length ) ) {
+ Window.AddChat( "&e/client generate: &cInvalid dimensions." );
+ } else {
+ if( width < 16 || height < 16 || length < 16 ) {
+ Window.AddChat( "&e/client generate: &cDimensions too small." );
+ return;
+ }
+ if( width > 1024 || height > 1024 || length > 1024 ) {
+ Window.AddChat( "&e/client generate: &cDimensions too large." );
+ return;
+ }
+ if( !( Window.Network is SinglePlayerServer ) ) {
+ Window.AddChat( "&e/client generate: &cThis command only works in singleplayer mode." );
+ return;
+ }
+ SinglePlayerServer server = (SinglePlayerServer)Window.Network;
+ server.NewMap();
+ Window.chatInInputBuffer = "";
+ server.MakeMap( width, height, length );
+ }
+ }
+ }
+}
diff --git a/ClassicalSharp/Network/SinglePlayerServer.cs b/ClassicalSharp/Singleplayer/Server.cs
similarity index 73%
rename from ClassicalSharp/Network/SinglePlayerServer.cs
rename to ClassicalSharp/Singleplayer/Server.cs
index 1153aa6b2..8b7e7cd84 100644
--- a/ClassicalSharp/Network/SinglePlayerServer.cs
+++ b/ClassicalSharp/Singleplayer/Server.cs
@@ -3,7 +3,7 @@ using System.Net;
using OpenTK;
using OpenTK.Input;
-namespace ClassicalSharp {
+namespace ClassicalSharp.Singleplayer {
public sealed class SinglePlayerServer : INetworkProcessor {
@@ -23,7 +23,8 @@ namespace ClassicalSharp {
}
game.RaiseBlockPermissionsChanged();
NewMap();
- MapLoaded();
+ MakeMap( 128, 128, 128 );
+ game.CommandManager.RegisterCommand( new GenerateCommand() );
}
public override void SendChat( string text ) {
@@ -48,7 +49,7 @@ namespace ClassicalSharp {
if( Disconnected ) return;
}
- void NewMap() {
+ internal void NewMap() {
ServerName = "Single player";
ServerMotd = "Generating a map..";
game.LocalPlayer.UserType = 0x64;
@@ -58,25 +59,25 @@ namespace ClassicalSharp {
game.SetNewScreen( new LoadingMapScreen( game, ServerName, ServerMotd ) );
}
- void MapLoaded() {
- game.SetNewScreen( new NormalScreen( game ) );
- int width = 16, height = 16, length = 16;
+ internal unsafe void MakeMap( int width, int height, int length ) {
byte[] map = new byte[width * height * length];
- MapSet( width, length, map, 0, height / 2 - 2, (byte)Block.Dirt );
- MapSet( width, length, map, height / 2 - 1, height / 2 - 1, (byte)Block.Grass );
+ var sw = System.Diagnostics.Stopwatch.StartNew();
+ fixed( byte* ptr = map ) {
+ MapSet( width, length, ptr, 0, height / 2 - 2, (byte)Block.Dirt );
+ MapSet( width, length, ptr, height / 2 - 1, height / 2 - 1, (byte)Block.Grass );
+ }
game.Map.UseRawMap( map, width, height, length );
game.RaiseOnNewMapLoaded();
+ game.SetNewScreen( new NormalScreen( game ) );
ResetPlayerPosition();
game.AddChat( "&ePlaying single player", CpeMessage.Status1 );
GC.Collect();
}
- void MapSet( int width, int length, byte[] map, int yStart, int yEnd, byte block ) {
+ unsafe void MapSet( int width, int length, byte* ptr, int yStart, int yEnd, byte block ) {
int startIndex = yStart * length * width;
int endIndex = ( yEnd * length + (length - 1) ) * width + (width - 1);
- for( int i = startIndex; i <= endIndex; i++ ) {
- map[i] = block;
- }
+ MemUtils.memset( (IntPtr)ptr, block, startIndex, endIndex - startIndex + 1 );
}
void ResetPlayerPosition() {
diff --git a/OpenTK/MemUtils.cs b/OpenTK/MemUtils.cs
new file mode 100644
index 000000000..90032e0eb
--- /dev/null
+++ b/OpenTK/MemUtils.cs
@@ -0,0 +1,67 @@
+using System;
+
+namespace OpenTK {
+
+ public static class MemUtils {
+
+ static MemUtils() {
+ use64Bit = IntPtr.Size == 8;
+ }
+ static bool use64Bit;
+
+ public static unsafe void memcpy( IntPtr srcPtr, IntPtr dstPtr, int bytes ) {
+ byte* srcByte, dstByte;
+ if( use64Bit ) {
+ ulong* srcLong = (ulong*)srcPtr, dstLong = (ulong*)dstPtr;
+ while( bytes >= 8 ) {
+ *dstLong++ = *srcLong++;
+ bytes -= 8;
+ }
+ srcByte = (byte*)srcLong; dstByte = (byte*)dstLong;
+ } else {
+ uint* srcInt = (uint*)srcPtr, dstInt = (uint*)dstPtr;
+ while( bytes >= 4 ) {
+ *dstInt++ = *srcInt++;
+ bytes -= 4;
+ }
+ srcByte = (byte*)srcInt; dstByte = (byte*)dstInt;
+ }
+
+ for( int i = 0; i < bytes; i++ ) {
+ *dstByte++ = *srcByte++;
+ }
+ }
+
+ public static unsafe void memset( IntPtr srcPtr, byte value, int startIndex, int bytes ) {
+ byte* srcByte = (byte*)srcPtr + startIndex;
+ // Make sure we do an aligned write/read for the bulk copy
+ while( bytes > 0 && ( startIndex & 0x7 ) != 0 ) {
+ *srcByte++ = value;
+ startIndex++;
+ bytes--;
+ }
+ uint valueInt = (uint)( ( value << 24 ) | ( value << 16 ) | ( value << 8 ) | value );
+
+ if( use64Bit ) {
+ ulong valueLong = ( (ulong)valueInt << 32 ) | valueInt;
+ ulong* srcLong = (ulong*)srcByte;
+ while( bytes >= 8 ) {
+ *srcLong++ = valueLong;
+ bytes -= 8;
+ }
+ srcByte = (byte*)srcLong;
+ } else {
+ uint* srcInt = (uint*)srcByte;
+ while( bytes >= 4 ) {
+ *srcInt++ = valueInt;
+ bytes -= 4;
+ }
+ srcByte = (byte*)srcInt;
+ }
+
+ for( int i = 0; i < bytes; i++ ) {
+ *srcByte++ = value;
+ }
+ }
+ }
+}
diff --git a/OpenTK/OpenTK.csproj b/OpenTK/OpenTK.csproj
index 74b55b2e3..96d48cce1 100644
--- a/OpenTK/OpenTK.csproj
+++ b/OpenTK/OpenTK.csproj
@@ -51,7 +51,6 @@
-
@@ -62,6 +61,7 @@
+
@@ -80,6 +80,7 @@
+
diff --git a/OpenTK/Configuration.cs b/OpenTK/Platform/Configuration.cs
similarity index 100%
rename from OpenTK/Configuration.cs
rename to OpenTK/Platform/Configuration.cs
diff --git a/OpenTK/SharpDX.Direct3D/Direct3D.cs b/OpenTK/SharpDX.Direct3D/Direct3D.cs
index d5da9b49b..be8f42bad 100644
--- a/OpenTK/SharpDX.Direct3D/Direct3D.cs
+++ b/OpenTK/SharpDX.Direct3D/Direct3D.cs
@@ -34,7 +34,6 @@ namespace SharpDX.Direct3D9 {
Adapters = new List( count );
for( int i = 0; i < count; i++ )
Adapters.Add( new AdapterInformation( this, i ) );
- memcpy64Bit = IntPtr.Size == 8;
}
public List Adapters;
@@ -104,29 +103,5 @@ namespace SharpDX.Direct3D9 {
if( res < 0 ) { throw new SharpDXException( res ); }
return new Device( devicePtr );
}
-
- // TODO: Place this in a utilities class.
- static bool memcpy64Bit;
- internal static unsafe void memcpy( IntPtr srcPtr, IntPtr dstPtr, int bytes ) {
- byte* srcByte, dstByte;
- if( memcpy64Bit ) {
- long* srcLong = (long*)srcPtr, dstLong = (long*)dstPtr;
- while( bytes >= 8 ) {
- *dstLong++ = *srcLong++;
- bytes -= 8;
- }
- srcByte = (byte*)srcLong; dstByte = (byte*)dstLong;
- } else {
- int* srcInt = (int*)srcPtr, dstInt = (int*)dstPtr;
- while( bytes >= 4 ) {
- *dstInt++ = *srcInt++;
- bytes -= 4;
- }
- srcByte = (byte*)srcInt; dstByte = (byte*)dstInt;
- }
- for( int i = 0; i < bytes; i++ ) {
- *dstByte++ = *srcByte++;
- }
- }
}
}
diff --git a/OpenTK/SharpDX.Direct3D/Resources.cs b/OpenTK/SharpDX.Direct3D/Resources.cs
index b725b1c6a..63fb0dadf 100644
--- a/OpenTK/SharpDX.Direct3D/Resources.cs
+++ b/OpenTK/SharpDX.Direct3D/Resources.cs
@@ -57,14 +57,14 @@ namespace SharpDX.Direct3D9 {
public void SetData( IntPtr data, int bytes, LockFlags flags ) {
IntPtr dst = Lock( 0, bytes, flags );
- Direct3D.memcpy( data, dst, bytes );
+ MemUtils.memcpy( data, dst, bytes );
Unlock();
}
public void SetData( T[] data, int bytes, LockFlags flags ) where T : struct {
IntPtr src = Interop.Fixed( ref data[0] );
IntPtr dst = Lock( 0, bytes, flags );
- Direct3D.memcpy( src, dst, bytes );
+ MemUtils.memcpy( src, dst, bytes );
Unlock();
}
@@ -108,7 +108,7 @@ namespace SharpDX.Direct3D9 {
public void SetData( IntPtr data, int bytes, int level, LockFlags flags ) {
LockedRectangle rect = LockRectangle( level, flags );
- Direct3D.memcpy( data, rect.DataPointer, bytes );
+ MemUtils.memcpy( data, rect.DataPointer, bytes );
UnlockRectangle( level );
}