Bold selected name, some minor cleanup.

This commit is contained in:
UnknownShadow200 2015-11-04 20:36:01 +11:00
parent 09faf5c45e
commit 8130d91fc3
16 changed files with 169 additions and 122 deletions

View File

@ -53,7 +53,9 @@ namespace ClassicalSharp {
void DrawTextImpl( FastBitmap fastBmp, ref DrawTextArgs args, int x, int y ) {
bool italic = args.Font.Style == FontStyle.Italic;
if( args.UseShadow ) {
int shadowX = x + 2, shadowY = y + 2;
int offset = ShaowOffset( args.Font.Size );
int shadowX = x + offset, shadowY = y + offset;
for( int i = 0; i < parts.Count; i++ ) {
TextPart part = parts[i];
part.TextColour = FastColour.Black;
@ -118,7 +120,8 @@ namespace ClassicalSharp {
if( args.Font.Style == FontStyle.Italic )
total.Width += Utils.CeilDiv( total.Height, italicSize );
if( args.UseShadow && parts.Count > 0 ) {
total.Width += 2; total.Height += 2;
int offset = ShaowOffset( args.Font.Size );
total.Width += offset; total.Height += offset;
}
return total;
}
@ -134,6 +137,12 @@ namespace ClassicalSharp {
return (int)'?';
}
int ShaowOffset( float fontSize ) {
if( fontSize < 9.9f ) return 1;
if( fontSize < 24.9f ) return 2;
return 3;
}
int PtToPx( int point ) {
return (int)Math.Ceiling( (float)point / 72 * 96 ); // TODO: non 96 dpi?
}

View File

@ -26,11 +26,8 @@ namespace ClassicalSharp {
(g, v) => g.Map.SetFogColour( FastColour.Parse( v ) ) ),
Make( -140, 0, "Clouds speed", Anchor.Centre, OnWidgetClick,
g => { StandardEnvRenderer env = game.EnvRenderer as StandardEnvRenderer;
return env == null ? "(not active)" : env.CloudsSpeed.ToString(); },
(g, v) => { StandardEnvRenderer env = game.EnvRenderer as StandardEnvRenderer;
if( env != null )
env.CloudsSpeed = Single.Parse( v ); } ),
g => g.Map.CloudsSpeed.ToString(),
(g, v) => g.Map.SetCloudsSpeed( Single.Parse( v ) ) ),
Make( -140, 50, "Clouds height", Anchor.Centre, OnWidgetClick,
g => g.Map.CloudHeight.ToString(),

View File

@ -16,13 +16,13 @@ namespace ClassicalSharp {
this.font = font;
this.boldFont = boldFont;
chatInputText = new StringBuffer( len );
chatInputText = new WrappableStringBuffer( len );
}
Texture chatInputTexture, caretTexture;
int caretPos = -1, typingLogPos = 0;
public int YOffset;
internal StringBuffer chatInputText;
internal WrappableStringBuffer chatInputText;
readonly Font font, boldFont;
static FastColour normalCaretCol = FastColour.White,

View File

@ -218,6 +218,7 @@
<Compile Include="Utils\StringBuffer.cs" />
<Compile Include="Utils\Utils.cs" />
<Compile Include="Utils\Vector3I.cs" />
<Compile Include="Utils\WrappableStringBuffer.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />

View File

@ -124,6 +124,7 @@ namespace ClassicalSharp {
EdgeBlock,
EdgeLevel,
CloudsLevel,
CloudsSpeed,
Weather,
SkyColour,

View File

@ -114,10 +114,10 @@ namespace ClassicalSharp.GraphicsAPI {
/// <summary> Sets the depth test compare function that is used when depth testing is enabled. </summary>
public abstract void DepthTestFunc( CompareFunc func );
/// <summary> Sets whether writing to the colour buffer is enabled. </summary>
/// <summary> Whether writing to the colour buffer is enabled. </summary>
public abstract bool ColourWrite { set; }
/// <summary> Sets whether writing to the depth buffer is enabled. </summary>
/// <summary> Whether writing to the depth buffer is enabled. </summary>
public abstract bool DepthWrite { set; }
/// <summary> Creates a vertex buffer that can have its data dynamically updated. </summary>
@ -135,7 +135,7 @@ namespace ClassicalSharp.GraphicsAPI {
/// but the index buffer's data cannot be updated after creation. </summary>
public abstract int CreateIb( ushort[] indices, int indicesCount );
/// <summary> Creates a static vertex buffer that has its data set at creation,
/// <summary> Creates a static index buffer that has its data set at creation,
/// but the index buffer's data cannot be updated after creation. </summary>
public abstract int CreateIb( IntPtr indices, int indicesCount );

View File

@ -29,6 +29,9 @@ namespace ClassicalSharp {
/// <summary> Height of the clouds in world space. </summary>
public int CloudHeight;
/// <summary> How fast clouds should travel across the map, defaults to 1. </summary>
public float CloudsSpeed = 1;
/// <summary> Colour applied to blocks located in direct sunlight. </summary>
public FastColour Sunlight;
public FastColour SunlightXSide, SunlightZSide, SunlightYBottom;
@ -45,14 +48,14 @@ namespace ClassicalSharp {
/// <summary> Unique uuid/guid of this particular map. </summary>
public Guid Uuid;
/// <summary> Block that surrounds map and is perpendicular to the Y plane. (default water) </summary>
/// <summary> Block that surrounds map the map horizontally (default water) </summary>
public Block EdgeBlock = Block.StillWater;
/// <summary> Height of the map edge in world space. </summary>
public int EdgeHeight;
/// <summary> Block that surrounds the map that is below the map, fills part of the vertical sides,
/// and also perpendicular to the Y plane. (default bedrock) </summary>
/// <summary> Block that surrounds the map that fills the bottom of the map horizontally,
/// fills part of the vertical sides of the map, and also surrounds map the map horizontally. (default bedrock) </summary>
public Block SidesBlock = Block.Bedrock;
/// <summary> Maximum height of the various parts of the map sides, in world space. </summary>
@ -79,6 +82,7 @@ namespace ClassicalSharp {
Uuid = Guid.NewGuid();
EdgeBlock = Block.StillWater;
SidesBlock = Block.Bedrock;
CloudsSpeed = 1;
ResetLight();
SkyCol = DefaultSkyColour;
@ -125,6 +129,10 @@ namespace ClassicalSharp {
/// EnvVariableChanged event with the variable 'CloudsLevel'. </summary>
public void SetCloudsLevel( int level ) { Set( level, ref CloudHeight, EnvVar.CloudsLevel ); }
/// <summary> Sets the current clouds speed, and raises the
/// EnvVariableChanged event with the variable 'CloudsSpeed'. </summary>
public void SetCloudsSpeed( float speed ) { Set( speed, ref CloudsSpeed, EnvVar.CloudsSpeed ); }
/// <summary> Sets the height of the map edges in world space, and raises the
/// EnvVariableChanged event with the variable 'EdgeLevel'. </summary>
public void SetEdgeLevel( int level ) { Set( level, ref EdgeHeight, EnvVar.EdgeLevel ); }
@ -214,14 +222,14 @@ namespace ClassicalSharp {
return mapData[(p.Y * Length + p.Z) * Width + p.X];
}
/// <summary> Returns the block at the given world coordinates withbounds checking,
/// <summary> Returns the block at the given world coordinates with bounds checking,
/// returning 0 is the coordinates were outside the map. </summary>
public byte SafeGetBlock( int x, int y, int z ) {
return IsValidPos( x, y, z ) ?
mapData[(y * Length + z) * Width + x] : (byte)0;
}
/// <summary> Returns the block at the given world coordinates withbounds checking,
/// <summary> Returns the block at the given world coordinates with bounds checking,
/// returning 0 is the coordinates were outside the map. </summary>
public byte SafeGetBlock( Vector3I p ) {
return IsValidPos( p.X, p.Y, p.Z ) ?

View File

@ -108,7 +108,6 @@ namespace ClassicalSharp {
while( reader.size > 0 ) {
byte opcode = reader.buffer[0];
Console.WriteLine( (PacketId)opcode );
// Fix for older D3 servers which wrote one byte too many for HackControl packets.
if( opcode == 0xFF && lastOpcode == PacketId.CpeHackControl ) {
reader.Remove( 1 );

View File

@ -12,7 +12,6 @@ namespace ClassicalSharp.Renderers {
}
int cloudsVb = -1, cloudVertices, skyVb = -1, skyVertices;
public float CloudsSpeed = 1;
bool legacy;
public void SetUseLegacyMode( bool legacy ) {
@ -92,7 +91,7 @@ namespace ClassicalSharp.Renderers {
void RenderClouds( double delta ) {
double time = game.accumulator;
float offset = (float)( time / 2048f * 0.6f * CloudsSpeed );
float offset = (float)( time / 2048f * 0.6f * map.CloudsSpeed );
graphics.SetMatrixMode( MatrixType.Texture );
Matrix4 matrix = Matrix4.Translate( offset, 0, 0 );
graphics.LoadMatrix( ref matrix );

View File

@ -2,15 +2,14 @@
namespace ClassicalSharp {
public sealed class StringBuffer {
public class StringBuffer {
char[] value, wrap;
int capacity;
protected char[] value;
protected int capacity;
public StringBuffer( int capacity ) {
this.capacity = capacity;
value = new char[capacity];
wrap = new char[capacity];
}
public StringBuffer Append( int index, char c ) {
@ -97,84 +96,6 @@ namespace ClassicalSharp {
return new String( value, 0, length );
}
public void WordWrap( ref string[] lines, ref int[] lineLens, int lineSize ) {
int len = Length;
for( int i = 0; i < lines.Length; i++ ) {
lines[i] = null;
lineLens[i] = 0;
}
// Need to make a copy because we mutate the characters.
char[] realText = value;
MakeWrapCopy();
int linesCount = 0;
for( int index = 0; index < capacity; index += lineSize ) {
if( value[index] == '\0' )
break;
int lineEnd = index + (lineSize - 1);
int nextLine = index + lineSize;
linesCount++;
// Do we need word wrapping?
bool needWrap = !IsWrapper( value[lineEnd] ) && nextLine < capacity && !IsWrapper( value[nextLine] );
int wrappedLen = needWrap ? WrapLine( index, lineSize ) : lineSize;
// Calculate the maximum size of this line
int lineLen = lineSize;
for( int i = lineEnd; i >= index; i-- ) {
if( value[i] != '\0' ) break;
lineLen--;
}
lineLens[index / lineSize] = Math.Min( lineLen, wrappedLen );
}
// Output the used lines
OutputLines( ref lines, linesCount, lineSize );
value = realText;
}
void MakeWrapCopy() {
int len = Length;
for( int i = 0; i < len; i++ )
wrap[i] = value[i];
for( int i = len; i < capacity; i++ )
wrap[i] = '\0';
value = wrap;
}
void OutputLines( ref string[] lines, int linesCount, int lineSize ) {
for( int i = 0; i < capacity; i++ ) {
if( value[i] == '\0' ) value[i] = ' ';
}
for( int i = 0; i < Math.Max( 1, linesCount ); i++ ) {
lines[i] = new String( value, i * lineSize, lineSize );
}
}
int WrapLine( int index, int lineSize ) {
int lineEnd = index + (lineSize - 1);
// wrap - but we don't want to wrap if the entire line is filled.
for( int i = lineEnd; i >= index + 1; i-- ) {
if( IsWrapper( value[i] ) ) {
for( int j = lineEnd; j >= i + 1; j-- ) {
InsertAt( index + lineSize, value[j] );
value[j] = ' ';
}
return (i + 1) - index;
}
}
return lineSize;
}
bool IsWrapper( char c ) {
return c == '\0' || c == ' ' || c == '-' || c == '>'
|| c == '<' || c == '/' || c == '\\';
}
public override string ToString() {
return new String( value, 0, Length );
}

View File

@ -0,0 +1,91 @@
using System;
namespace ClassicalSharp {
public sealed class WrappableStringBuffer : StringBuffer {
char[] wrap;
public WrappableStringBuffer( int capacity ) : base( capacity ) {
wrap = new char[capacity];
}
public void WordWrap( ref string[] lines, ref int[] lineLens, int lineSize ) {
int len = Length;
for( int i = 0; i < lines.Length; i++ ) {
lines[i] = null;
lineLens[i] = 0;
}
// Need to make a copy because we mutate the characters.
char[] realText = value;
MakeWrapCopy();
int linesCount = 0;
for( int index = 0; index < capacity; index += lineSize ) {
if( value[index] == '\0' )
break;
int lineEnd = index + (lineSize - 1);
int nextLine = index + lineSize;
linesCount++;
// Do we need word wrapping?
bool needWrap = !IsWrapper( value[lineEnd] ) && nextLine < capacity && !IsWrapper( value[nextLine] );
int wrappedLen = needWrap ? WrapLine( index, lineSize ) : lineSize;
// Calculate the maximum size of this line
int lineLen = lineSize;
for( int i = lineEnd; i >= index; i-- ) {
if( value[i] != '\0' ) break;
lineLen--;
}
lineLens[index / lineSize] = Math.Min( lineLen, wrappedLen );
}
// Output the used lines
OutputLines( ref lines, linesCount, lineSize );
value = realText;
}
void MakeWrapCopy() {
int len = Length;
for( int i = 0; i < len; i++ )
wrap[i] = value[i];
for( int i = len; i < capacity; i++ )
wrap[i] = '\0';
value = wrap;
}
void OutputLines( ref string[] lines, int linesCount, int lineSize ) {
for( int i = 0; i < capacity; i++ ) {
if( value[i] == '\0' ) value[i] = ' ';
}
for( int i = 0; i < Math.Max( 1, linesCount ); i++ ) {
lines[i] = new String( value, i * lineSize, lineSize );
}
}
int WrapLine( int index, int lineSize ) {
int lineEnd = index + (lineSize - 1);
// wrap - but we don't want to wrap if the entire line is filled.
for( int i = lineEnd; i >= index + 1; i-- ) {
if( IsWrapper( value[i] ) ) {
for( int j = lineEnd; j >= i + 1; j-- ) {
InsertAt( index + lineSize, value[j] );
value[j] = ' ';
}
return (i + 1) - index;
}
}
return lineSize;
}
bool IsWrapper( char c ) {
return c == '\0' || c == ' ' || c == '-' || c == '>'
|| c == '<' || c == '/' || c == '\\';
}
}
}

View File

@ -8,9 +8,11 @@ namespace Launcher2 {
public sealed class ClassiCubeServersScreen : LauncherInputScreen {
const int tableIndex = 6;
Font boldInputFont;
public ClassiCubeServersScreen( LauncherWindow game ) : base( game ) {
titleFont = new Font( "Arial", 16, FontStyle.Bold );
inputFont = new Font( "Arial", 13, FontStyle.Regular );
boldInputFont = new Font( "Arial", 13, FontStyle.Bold );
enterIndex = 4;
widgets = new LauncherWidget[7];
}
@ -43,6 +45,15 @@ namespace Launcher2 {
Resize();
}
}
protected override void RedrawLastInput() {
base.RedrawLastInput();
if( lastInput == widgets[3] ) {
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
table.SelectedHash = widgets[3].Text;
Resize();
}
}
public override void Init() {
base.Init();
@ -55,13 +66,13 @@ namespace Launcher2 {
using( drawer ) {
drawer.SetBitmap( game.Framebuffer );
game.ClearArea( 0, 0, game.Width, 100 );
drawer.Clear( game.clearColour, 0, 100,
drawer.Clear( game.clearColour, 0, 100,
game.Width, game.Height - 100 );
Draw();
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
table.ClampIndex();
table.Redraw( drawer, inputFont, titleFont );
table.Redraw( drawer, inputFont, titleFont, boldInputFont );
}
Dirty = true;
}
@ -69,31 +80,32 @@ namespace Launcher2 {
void Draw() {
widgetIndex = 0;
MakeLabelAt( "Search", titleFont, Anchor.Centre, Anchor.LeftOrTop, -200, 10 );
MakeInput( Get(), 270, Anchor.LeftOrTop, false, -25, 5, 32 );
MakeLabelAt( "Search", titleFont, Anchor.Centre, Anchor.LeftOrTop, -190, 10 );
MakeInput( Get(), 270, Anchor.LeftOrTop, false, -5, 5, 32 );
MakeLabelAt( "../play/", inputFont, Anchor.Centre, Anchor.LeftOrTop, -210, 55 );
MakeInput( Get(), 320, Anchor.LeftOrTop, false, -20, 50, 32 );
MakeLabelAt( "/play/", inputFont, Anchor.Centre, Anchor.LeftOrTop, -215, 55 );
MakeInput( Get(), 310, Anchor.LeftOrTop, false, -35, 50, 32 );
((LauncherInputWidget)widgets[3]).ClipboardFilter = HashFilter;
MakeButtonAt( "Connect", 100, 30, titleFont, Anchor.LeftOrTop,
180, 5, ConnectToServer );
MakeButtonAt( "Back", 70, 30, titleFont, Anchor.LeftOrTop,
195, 50, (x, y) => game.SetScreen( new ClassiCubeScreen( game ) ) );
195, 5, (x, y) => game.SetScreen( new ClassiCubeScreen( game ) ) );
MakeButtonAt( "Connect", 100, 30, titleFont, Anchor.LeftOrTop,
180, 50, ConnectToServer );
MakeTableWidget();
}
void MakeTableWidget() {
if( widgets[tableIndex] != null ) {
LauncherTableWidget table = (LauncherTableWidget)widgets[tableIndex];
table.Redraw( drawer, inputFont, titleFont );
table.Redraw( drawer, inputFont, titleFont, boldInputFont );
return;
}
LauncherTableWidget widget = new LauncherTableWidget( game );
widget.CurrentIndex = 0;
widget.SetEntries( game.Session.Servers );
widget.DrawAt( drawer, inputFont, titleFont, Anchor.LeftOrTop, Anchor.LeftOrTop, 0, 100 );
widget.DrawAt( drawer, inputFont, titleFont, boldInputFont,
Anchor.LeftOrTop, Anchor.LeftOrTop, 0, 100 );
widget.NeedRedraw = Resize;
widget.SelectedChanged = SelectedChanged;
@ -136,6 +148,7 @@ namespace Launcher2 {
public override void Dispose() {
base.Dispose();
boldInputFont.Dispose();
game.Window.Mouse.WheelChanged -= MouseWheelChanged;
}
}

View File

@ -66,7 +66,7 @@ namespace Launcher2 {
}
}
protected void RedrawLastInput() {
protected virtual void RedrawLastInput() {
using( drawer ) {
drawer.SetBitmap( game.Framebuffer );
if( lastInput.Width > lastInput.ButtonWidth )
@ -94,7 +94,7 @@ namespace Launcher2 {
}
protected LauncherInputWidget lastInput;
protected void InputClick( int mouseX, int mouseY ) {
protected virtual void InputClick( int mouseX, int mouseY ) {
LauncherInputWidget input = (LauncherInputWidget)selectedWidget;
using( drawer ) {
drawer.SetBitmap( game.Framebuffer );

View File

@ -41,6 +41,9 @@ namespace Launcher2 {
lastPress = DateTime.UtcNow;
}
SelectedChanged( entry.Hash );
SelectedHash = entry.Hash;
NeedRedraw();
lastIndex = i;
break;
}

View File

@ -13,6 +13,7 @@ namespace Launcher2 {
public Action NeedRedraw;
public Action<string> SelectedChanged;
public string SelectedHash;
TableEntry[] entries, usedEntries;
internal List<ServerListEntry> servers;
@ -58,26 +59,26 @@ namespace Launcher2 {
public int Y, Height;
}
public void DrawAt( IDrawer2D drawer, Font font, Font titleFont,
public void DrawAt( IDrawer2D drawer, Font font, Font titleFont, Font boldFont,
Anchor horAnchor, Anchor verAnchor, int x, int y ) {
CalculateOffset( x, y, horAnchor, verAnchor );
Redraw( drawer, font, titleFont );
Redraw( drawer, font, titleFont, boldFont );
}
static FastColour backCol = new FastColour( 120, 85, 151 ), foreCol = new FastColour( 160, 133, 186 );
static FastColour scrollCol = new FastColour( 200, 184, 216 );
public void Redraw( IDrawer2D drawer, Font font, Font titleFont ) {
public void Redraw( IDrawer2D drawer, Font font, Font titleFont, Font boldFont ) {
Utils.Clamp( ref ColumnWidths[0], 20, Window.Width - 20 );
int x = X + 5;
DrawGrid( drawer, font, titleFont );
x += DrawColumn( drawer, true, font, titleFont, "Name", ColumnWidths[0], x, e => e.Name ) + 5;
x += DrawColumn( drawer, false, font, titleFont, "Players", ColumnWidths[1], x, e => e.Players ) + 5;
x += DrawColumn( drawer, true, font, titleFont, boldFont, "Name", ColumnWidths[0], x, e => e.Name ) + 5;
x += DrawColumn( drawer, false, font, titleFont, boldFont, "Players", ColumnWidths[1], x, e => e.Players ) + 5;
Width = Window.Width;
DrawScrollbar( drawer );
}
int DrawColumn( IDrawer2D drawer, bool separator, Font font, Font titleFont,
int DrawColumn( IDrawer2D drawer, bool separator, Font font, Font titleFont, Font boldFont,
string header, int maxWidth, int x, Func<TableEntry, string> filter ) {
int y = Y + 10;
DrawTextArgs args = new DrawTextArgs( header, titleFont, true );
@ -87,6 +88,9 @@ namespace Launcher2 {
for( int i = CurrentIndex; i < Count; i++ ) {
args = new DrawTextArgs( filter( usedEntries[i] ), font, true );
if( usedEntries[i].Hash == SelectedHash ) {
args.Font = boldFont;
}
if( !DrawColumnEntry( drawer, ref args, maxWidth, x, ref y, ref usedEntries[i] ) ) {
maxIndex = i;
break;

View File

@ -46,7 +46,8 @@ namespace Launcher2 {
drawer.DrawRect( FastColour.Black, X + 2, Y + 2, Width - 4, Height - 4 );
args.SkipPartsCheck = true;
drawer.DrawText( ref args, X + 7, Y + 2 );
int y = Y + 2 + (Height - size.Height ) / 2;
drawer.DrawText( ref args, X + 5, y );
}
/// <summary> Appends a character to the end of the currently entered text. </summary>