From 85eef80e214e0f5681e9e539cb0abdc399271f19 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 10 Oct 2015 12:25:40 +1100 Subject: [PATCH] Can pass initial texture pack as a command line argument to the client. Add a texture pack selection screen. --- ClassicalSharp/2D/Screens/FilesScreen.cs | 165 ++++++++++++++++++ .../2D/Screens/Menu/KeyMappingsScreen.cs | 2 +- .../2D/Screens/Menu/MenuInputScreen.cs | 1 + .../2D/Screens/Menu/OptionsScreen.cs | 5 +- ClassicalSharp/2D/Screens/Menu/PauseScreen.cs | 2 +- ClassicalSharp/2D/Widgets/TextInputWidget.cs | 6 +- ClassicalSharp/ClassicalSharp.csproj | 3 +- ClassicalSharp/Game/Game.cs | 9 +- ClassicalSharp/Program.cs | 6 +- OpenTK/Debug.cs | 2 +- 10 files changed, 188 insertions(+), 13 deletions(-) create mode 100644 ClassicalSharp/2D/Screens/FilesScreen.cs diff --git a/ClassicalSharp/2D/Screens/FilesScreen.cs b/ClassicalSharp/2D/Screens/FilesScreen.cs new file mode 100644 index 000000000..7b7ca8ee4 --- /dev/null +++ b/ClassicalSharp/2D/Screens/FilesScreen.cs @@ -0,0 +1,165 @@ +using System; +using System.Drawing; +using OpenTK.Input; +using System.IO; +using ClassicalSharp.TexturePack; + +namespace ClassicalSharp { + + public abstract class FilesScreen : Screen { + + public FilesScreen( Game game ) : base( game ) { + } + + protected Font textFont, arrowFont, titleFont; + protected string[] files; + int currentIndex; + protected ButtonWidget[] buttons; + + TextWidget title; + protected string titleText; + + public override void Init() { + textFont = new Font( "Arial", 14, FontStyle.Bold ); + arrowFont = new Font( "Arial", 18, FontStyle.Bold ); + titleFont = new Font( "Arial", 16, FontStyle.Bold ); + title = TextWidget.Create( game, 0, -130, titleText, Anchor.Centre, Anchor.Centre, titleFont ); + title.Init(); + + buttons = new ButtonWidget[] { + MakeText( 0, -80, Get( 0 ) ), + MakeText( 0, -40, Get( 1 ) ), + MakeText( 0, 0, Get( 2 ) ), + MakeText( 0, 40, Get( 3 ) ), + MakeText( 0, 80, Get( 4 ) ), + + Make( -160, 0, "<", (g, w) => PageClick( false ) ), + Make( 160, 0, ">", (g, w) => PageClick( true ) ), + null, + }; + } + + string Get( int index ) { + return index < files.Length ? files[index] : "-----"; + } + + public override void Dispose() { + for( int i = 0; i < buttons.Length; i++ ) + buttons[i].Dispose(); + textFont.Dispose(); + arrowFont.Dispose(); + title.Dispose(); + titleFont.Dispose(); + } + + ButtonWidget MakeText( int x, int y, string text ) { + return ButtonWidget.Create( game, x, y, 240, 30, text, + Anchor.Centre, Anchor.Centre, textFont, TextButtonClick ); + } + + ButtonWidget Make( int x, int y, string text, Action onClick ) { + return ButtonWidget.Create( game, x, y, 40, 40, text, + Anchor.Centre, Anchor.Centre, arrowFont, onClick ); + } + + protected abstract void TextButtonClick( Game game, ButtonWidget widget ); + + void PageClick( bool forward ) { + currentIndex += forward ? 5 : -5; + if( currentIndex >= files.Length ) + currentIndex -= 5; + if( currentIndex < 0 ) + currentIndex = 0; + + for( int i = 0; i < 5; i++ ) { + buttons[i].SetText( Get( currentIndex + i ) ); + } + } + + public override bool HandlesMouseMove( int mouseX, int mouseY ) { + for( int i = 0; i < buttons.Length; i++ ) + buttons[i].Active = false; + + for( int i = 0; i < buttons.Length; i++ ) { + ButtonWidget widget = buttons[i]; + if( widget.Bounds.Contains( mouseX, mouseY ) ) { + widget.Active = true; + return true; + } + } + return false; + } + + public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) { + if( button != MouseButton.Left ) return false; + for( int i = 0; i < buttons.Length; i++ ) { + ButtonWidget widget = buttons[i]; + if( widget.Bounds.Contains( mouseX, mouseY ) ) { + widget.OnClick( game, widget ); + return true; + } + } + return false; + } + + public override bool HandlesAllInput { + get { return true; } + } + + public override void OnResize( int oldWidth, int oldHeight, int width, int height ) { + for( int i = 0; i < buttons.Length; i++ ) + buttons[i].OnResize( oldWidth, oldHeight, width, height ); + title.OnResize( oldWidth, oldHeight, width, height ); + } + + public override void Render( double delta ) { + graphicsApi.Draw2DQuad( 0, 0, game.Width, game.Height, new FastColour( 60, 60, 60, 160 ) ); + graphicsApi.Texturing = true; + title.Render( delta ); + for( int i = 0; i < buttons.Length; i++ ) + buttons[i].Render( delta ); + graphicsApi.Texturing = false; + } + } + + public sealed class TexturePackScreen : FilesScreen { + + public TexturePackScreen( Game game ) : base( game ) { + titleText = "Select a texture pack zip"; + string directory = Environment.CurrentDirectory; + files = Directory.GetFiles( directory, "*.zip", SearchOption.AllDirectories ); + + for( int i = 0; i < files.Length; i++ ) { + string absolutePath = files[i]; + files[i] = absolutePath.Substring( directory.Length + 1 ); + } + } + + public override bool HandlesKeyDown( Key key ) { + if( key == Key.Escape ) { + game.SetNewScreen( new NormalScreen( game ) ); + return true; + } + return false; + } + + public override void Init() { + base.Init(); + buttons[buttons.Length - 1] = + Make( 0, 5, "Back to menu", (g, w) => g.SetNewScreen( new PauseScreen( g ) ) ); + } + + ButtonWidget Make( int x, int y, string text, Action onClick ) { + return ButtonWidget.Create( game, x, y, 240, 35, text, + Anchor.Centre, Anchor.BottomOrRight, titleFont, onClick ); + } + + protected override void TextButtonClick( Game game, ButtonWidget widget ) { + string path = widget.Text; + if( File.Exists( path ) ) { + TexturePackExtractor extractor = new TexturePackExtractor(); + extractor.Extract( path, game ); + } + } + } +} diff --git a/ClassicalSharp/2D/Screens/Menu/KeyMappingsScreen.cs b/ClassicalSharp/2D/Screens/Menu/KeyMappingsScreen.cs index 0edf5d917..869e55beb 100644 --- a/ClassicalSharp/2D/Screens/Menu/KeyMappingsScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/KeyMappingsScreen.cs @@ -35,7 +35,7 @@ namespace ClassicalSharp { MakeKeys( 0, 11, -140 ); MakeKeys( 11, 11, 140 ); - buttons[index] = Make( 0, 5, "Back to menu", Anchor.BottomOrRight, (g, w) => g.SetNewScreen( new PauseScreen( g ) ) ); + buttons[index] = Make( 0, 5, "Back to menu", Anchor.BottomOrRight, (g, w) => g.SetNewScreen( new OptionsScreen( g ) ) ); statusWidget = TextWidget.Create( game, 0, 150, "", Anchor.Centre, Anchor.Centre, regularFont ); } diff --git a/ClassicalSharp/2D/Screens/Menu/MenuInputScreen.cs b/ClassicalSharp/2D/Screens/Menu/MenuInputScreen.cs index ebd37cb5e..2548fd671 100644 --- a/ClassicalSharp/2D/Screens/Menu/MenuInputScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/MenuInputScreen.cs @@ -87,6 +87,7 @@ namespace ClassicalSharp { protected void UpdateDescription( ButtonWidget widget ) { if( descWidget != null ) descWidget.Dispose(); + if( widget.GetValue == null ) return; string text = widget.Text + ": " + widget.GetValue( game ); descWidget = TextWidget.Create( game, 0, 100, text, Anchor.Centre, Anchor.Centre, regularFont ); diff --git a/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs b/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs index 617a82894..c4e3cc2b4 100644 --- a/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/OptionsScreen.cs @@ -36,8 +36,11 @@ namespace ClassicalSharp { (g, v) => { g.Chat.FontSize = Int32.Parse( v ); Options.Set( OptionsKey.FontSize, v ); } ), + Make( 140, 50, "Key mappings", Anchor.Centre, + (g, w) => g.SetNewScreen( new KeyMappingsScreen( g ) ), null, null ), + !network.IsSinglePlayer ? null : - Make( 140, 50, "Singleplayer physics", Anchor.Centre, OnWidgetClick, + Make( -140, -100, "Singleplayer physics", Anchor.Centre, OnWidgetClick, g => ((SinglePlayerServer)network).physics.Enabled ? "yes" : "no", (g, v) => ((SinglePlayerServer)network).physics.Enabled = (v == "yes") ), diff --git a/ClassicalSharp/2D/Screens/Menu/PauseScreen.cs b/ClassicalSharp/2D/Screens/Menu/PauseScreen.cs index 4c7f8053d..6cbaf37f8 100644 --- a/ClassicalSharp/2D/Screens/Menu/PauseScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/PauseScreen.cs @@ -21,7 +21,7 @@ namespace ClassicalSharp { buttons = new ButtonWidget[] { Make( 0, -100, "Options", Anchor.Centre, (g, w) => g.SetNewScreen( new OptionsScreen( g ) ) ), Make( 0, -50, "Environment settings", Anchor.Centre, (g, w) => g.SetNewScreen( new EnvSettingsScreen( g ) ) ), - Make( 0, 0, "Key mappings", Anchor.Centre, (g, w) => g.SetNewScreen( new KeyMappingsScreen( g ) ) ), + Make( 0, 0, "Select texture pack", Anchor.Centre, (g, w) => g.SetNewScreen( new TexturePackScreen( g ) ) ), Make( 0, 50, "Save level", Anchor.Centre, (g, w) => g.SetNewScreen( new SaveLevelScreen( g ) ) ), // TODO: singleplayer Make( 0, 50, "Load/Save/Gen level", Docking.Centre, (g, w) => g.SetNewScreen( new SaveLevelScreen( g ) ) ), Make( 0, 55, "Back to game", Anchor.BottomOrRight, (g, w) => g.SetNewScreen( new NormalScreen( g ) ) ), diff --git a/ClassicalSharp/2D/Widgets/TextInputWidget.cs b/ClassicalSharp/2D/Widgets/TextInputWidget.cs index 6a21681cc..d43b4e22e 100644 --- a/ClassicalSharp/2D/Widgets/TextInputWidget.cs +++ b/ClassicalSharp/2D/Widgets/TextInputWidget.cs @@ -33,11 +33,9 @@ namespace ClassicalSharp { X = 10; DrawTextArgs caretArgs = new DrawTextArgs( "_", Color.White, false ); chatCaretTexture = game.Drawer2D.MakeTextTexture( boldFont, 0, 0, ref caretArgs ); - string value = chatInputText.GetString(); - - if( chatInputText.Empty ) { + string value = chatInputText.GetString(); + if( chatInputText.Empty || caretPos >= value.Length ) caretPos = -1; - } Size size = game.Drawer2D.MeasureSize( value, font, false ); if( caretPos == -1 ) { diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index aba30613f..7d25fe73f 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -19,7 +19,7 @@ 4 - x86 + AnyCPU 4194304 False Auto @@ -73,6 +73,7 @@ + diff --git a/ClassicalSharp/Game/Game.cs b/ClassicalSharp/Game/Game.cs index f4e5693f2..a58d347a1 100644 --- a/ClassicalSharp/Game/Game.cs +++ b/ClassicalSharp/Game/Game.cs @@ -66,7 +66,7 @@ namespace ClassicalSharp { int width, height; public AsyncDownloader AsyncDownloader; public Matrix4 View, Projection; - public int MouseSensitivity = 30; + public int MouseSensitivity = 40; public bool HideGui = false, ShowFPS = true; public Animations Animations; internal int CloudsTextureId, RainTextureId, SnowTextureId; @@ -89,6 +89,11 @@ namespace ClassicalSharp { Mppass = mppass; this.skinServer = skinServer; this.defaultTexPack = defaultTexPack; + + if( !File.Exists( defaultTexPack ) ) { + Utils.LogWarning( defaultTexPack + " not found" ); + this.defaultTexPack = "default.zip"; + } } protected override void OnLoad( EventArgs e ) { @@ -109,7 +114,7 @@ namespace ClassicalSharp { Chat.FontSize = Options.GetInt( OptionsKey.FontSize, 6, 30, 12 ); Drawer2D = new GdiPlusDrawer2D( Graphics ); defaultIb = Graphics.MakeDefaultIb(); - MouseSensitivity = Options.GetInt( OptionsKey.Sensitivity, 1, 100, 30 ); + MouseSensitivity = Options.GetInt( OptionsKey.Sensitivity, 1, 100, 40 ); ModelCache = new ModelCache( this ); ModelCache.InitCache(); diff --git a/ClassicalSharp/Program.cs b/ClassicalSharp/Program.cs index acb050f17..b247c9700 100644 --- a/ClassicalSharp/Program.cs +++ b/ClassicalSharp/Program.cs @@ -24,7 +24,8 @@ namespace ClassicalSharp { if( args.Length == 0 || args.Length == 1 ) { Utils.Log( "Starting singleplayer mode." ); const string skinServer = "http://s3.amazonaws.com/MinecraftSkins/"; - using( Game game = new Game( "LocalPlayer", null, skinServer, "default.zip" ) ) { + string pack = args.Length >= 1 ? args[0] : "default.zip"; + using( Game game = new Game( "LocalPlayer", null, skinServer, pack ) ) { game.Run(); } } else if( args.Length < 4 ) { @@ -50,7 +51,8 @@ namespace ClassicalSharp { } string skinServer = args.Length >= 5 ? args[4] : "http://s3.amazonaws.com/MinecraftSkins/"; - using( Game game = new Game( args[0], args[1], skinServer, "default.zip" ) ) { + string pack = args.Length >= 6 ? args[5] : "default.zip"; + using( Game game = new Game( args[0], args[1], skinServer, pack ) ) { game.IPAddress = ip; game.Port = port; game.Run(); diff --git a/OpenTK/Debug.cs b/OpenTK/Debug.cs index 68d31563f..9321f2a4e 100644 --- a/OpenTK/Debug.cs +++ b/OpenTK/Debug.cs @@ -1,4 +1,4 @@ -#define DEBUG_OPENTK +//#define DEBUG_OPENTK using System; namespace OpenTK {