Default.png should only not show pixels with A = 0, make clouds height be able to set to +-10,000, make snow/rain nicer, more work on 'alt text' input box.

This commit is contained in:
UnknownShadow200 2015-11-11 11:18:29 +11:00
parent c5a1f5a27e
commit cc0dd16c42
10 changed files with 223 additions and 62 deletions

View File

@ -90,7 +90,7 @@ namespace ClassicalSharp {
int fontX = srcX + xx * srcWidth / dstWidth;
int pixel = fontRow[fontX];
if( (byte)(pixel >> 24) < 127 ) continue;
if( (byte)(pixel >> 24) == 0 ) continue;
int col = pixel & ~0xFFFFFF;
col |= ((pixel & 0xFF) * textCol.B / 255);

View File

@ -59,7 +59,7 @@ namespace ClassicalSharp {
new HexColourValidator(),
new HexColourValidator(),
new RealValidator( 0, 1000 ),
new IntegerValidator( -1000, 1000 ),
new IntegerValidator( -10000, 10000 ),
new HexColourValidator(),
new HexColourValidator(),
new IntegerValidator( 0, 2 ),

View File

@ -0,0 +1,107 @@
using System;
using System.Drawing;
namespace ClassicalSharp {
public sealed partial class AltTextInputWidget : Widget {
Element[] elements;
void InitData() {
elements = new Element[] {
new Element( "Colours", 8 * 3, 3, "&0█&1█&2█&3█&4█&5█&6█&7█&8█&9█&a█&b█&c█&d█&e█&f█" ),
new Element( "Math", 16, 1, "ƒ½¼αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°√ⁿ²" ),
new Element( "Line/Box", 17, 1, "░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀■" ),
new Element( "Letters", 17, 1, "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜáíóúñÑ" ),
new Element( "Other", 16, 1, "☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼⌂¢£¥₧ªº¿⌐¬¡«»∙·" ),
};
}
struct Element {
public string Title;
public Size TitleSize;
public string Contents;
public int ItemsPerRow;
public int CharsPerItem;
public Element( string title, int itemsPerRow, int charsPerItem, string contents ) {
Title = title;
TitleSize = Size.Empty;
Contents = contents;
ItemsPerRow = itemsPerRow;
CharsPerItem = charsPerItem;
}
}
unsafe void MeasureContentSizes( Element e, Font font, Size* sizes ) {
string s = new String( '\0', e.CharsPerItem );
DrawTextArgs args = new DrawTextArgs( s, font, false );
// avoid allocating temporary strings here
fixed( char* ptr = s ) {
for( int i = 0; i < e.Contents.Length; i += e.CharsPerItem ) {
for( int j = 0; j < e.CharsPerItem; j++ )
ptr[j] = e.Contents[i + j];
sizes[i / e.CharsPerItem] = game.Drawer2D.MeasureChatSize( ref args );
}
}
}
unsafe Size CalculateContentSize( Element e, Size* sizes, out Size elemSize ) {
int wrap = e.ItemsPerRow / e.CharsPerItem;
elemSize = Size.Empty;
for( int i = 0; i < e.Contents.Length; i += e.CharsPerItem )
elemSize.Width = Math.Max( elemSize.Width, sizes[i / e.CharsPerItem].Width );
elemSize.Width += contentSpacing;
elemSize.Height = sizes[0].Height + contentSpacing;
int rows = Utils.CeilDiv( e.Contents.Length / e.CharsPerItem, wrap );
return new Size( elemSize.Width * wrap, elemSize.Height * rows );
}
const int titleSpacing = 10, contentSpacing = 5;
int MeasureTitles( Font font ) {
int totalWidth = 0;
DrawTextArgs args = new DrawTextArgs( null, font, false );
for( int i = 0; i < elements.Length; i++ ) {
args.Text = elements[i].Title;
elements[i].TitleSize = game.Drawer2D.MeasureChatSize( ref args );
elements[i].TitleSize.Width += titleSpacing;
totalWidth += elements[i].TitleSize.Width;
}
return totalWidth;
}
void DrawTitles( IDrawer2D drawer, Font font ) {
int x = 0;
DrawTextArgs args = new DrawTextArgs( null, font, false );
for( int i = 0; i < elements.Length; i++ ) {
args.Text = elements[i].Title;
FastColour col = i == selectedIndex ? new FastColour( 30, 30, 30, 200 ) :
new FastColour( 60, 60, 60, 200 );
Size size = elements[i].TitleSize;
drawer.Clear( col, x, 0, size.Width, size.Height );
drawer.DrawChatText( ref args, x + titleSpacing / 2, 0 );
x += size.Width;
}
}
unsafe void DrawContent( IDrawer2D drawer, Font font, Element e, int yOffset ) {
string s = new String( '\0', e.CharsPerItem );
int wrap = e.ItemsPerRow;
DrawTextArgs args = new DrawTextArgs( s, font, false );
fixed( char* ptr = s ) {
for( int i = 0; i < e.Contents.Length; i += e.CharsPerItem ) {
for( int j = 0; j < e.CharsPerItem; j++ )
ptr[j] = e.Contents[i + j];
int item = i / e.CharsPerItem;
int x = (item % wrap) * elementSize.Width, y = (item / wrap) * elementSize.Height;
y += yOffset;
drawer.DrawChatText( ref args, x, y );
}
}
}
}
}

View File

@ -1,7 +1,6 @@
using System;
using System.Drawing;
using OpenTK.Input;
using System.Windows.Forms;
namespace ClassicalSharp {
@ -9,7 +8,7 @@ namespace ClassicalSharp {
public AltTextInputWidget( Game game, Font font, Font boldFont, TextInputWidget parent ) : base( game ) {
HorizontalAnchor = Anchor.LeftOrTop;
VerticalAnchor = Anchor.LeftOrTop;
VerticalAnchor = Anchor.BottomOrRight;
this.font = font;
this.boldFont = boldFont;
this.parent = parent;
@ -18,55 +17,91 @@ namespace ClassicalSharp {
Texture chatInputTexture;
readonly Font font, boldFont;
TextInputWidget parent;
Size partSize;
Size elementSize;
public int YOffset;
public bool Active;
public void SetActive( bool active ) {
Active = active;
Height = active ? chatInputTexture.Height : 0;
}
public override void Render( double delta ) {
chatInputTexture.Render( graphicsApi );
}
public override void Init() {
X = 5; Y = 45;
DrawString();
X = 5; Y = YOffset;
InitData();
Redraw();
}
void Redraw() {
Make( elements[selectedIndex], font );
Width = chatInputTexture.Width;
Height = chatInputTexture.Height;
}
static FastColour backColour = new FastColour( 60, 60, 60, 200 );
void DrawString() {
DrawTextArgs args = new DrawTextArgs( "Text ", font, false );
partSize = game.Drawer2D.MeasureChatSize( ref args );
Size size = new Size( partSize.Width * 6, partSize.Height * 3 );
unsafe void Make( Element e, Font font ) {
Size* sizes = stackalloc Size[e.Contents.Length / e.CharsPerItem];
MeasureContentSizes( e, font, sizes );
Size bodySize = CalculateContentSize( e, sizes, out elementSize );
int titleWidth = MeasureTitles( font ), titleHeight = elements[0].TitleSize.Height;
Size size = new Size( Math.Max( bodySize.Width, titleWidth ), bodySize.Height + titleHeight );
using( Bitmap bmp = IDrawer2D.CreatePow2Bitmap( size ) ) {
using( IDrawer2D drawer = game.Drawer2D ) {
drawer.SetBitmap( bmp );
drawer.Clear( backColour, 0, 0, size.Width, size.Height );
for( int code = 0; code <= 15; code++ ) {
int c = code < 10 ? '0' + code : 'a' + (code - 10);
args.Text = "&" + (char)c + "Text";
int x = (code % 6);
int y = (code / 6);
drawer.DrawChatText( ref args, x * partSize.Width, y * partSize.Height );
}
DrawTitles( drawer, font );
drawer.Clear( new FastColour( 30, 30, 30, 200 ), 0, titleHeight,
size.Width, bodySize.Height );
DrawContent( drawer, font, e, titleHeight );
chatInputTexture = drawer.Make2DTexture( bmp, size, X, Y );
}
}
Height = size.Height;
Width = size.Width;
}
}
public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
int selectedIndex = 0;
public override bool HandlesMouseClick( int mouseX, int mouseY, MouseButton button ) {
mouseX -= X; mouseY -= Y;
mouseX /= partSize.Width; mouseY /= partSize.Height;
game.Chat.Add( "CLICKY CLICK" + mouseX + "," + mouseY );
int code = mouseY * 6 + mouseX;
if( code <= 15 ) {
int c = code < 10 ? '0' + code : 'a' + (code - 10);
string text = "&" + (char)c;
parent.AppendText( text );
if( IntersectsHeader( mouseX, mouseY ) ) {
Dispose();
Redraw();
} else {
IntersectsBody( mouseX, mouseY );
}
return true;
}
bool IntersectsHeader( int widgetX, int widgetY ) {
Rectangle bounds = new Rectangle( 0, 0, 0, 0 );
for( int i = 0; i < elements.Length; i++ ) {
Size size = elements[i].TitleSize;
bounds.Width = size.Width; bounds.Height = size.Height;
if( bounds.Contains( widgetX, widgetY ) ) {
selectedIndex = i;
return true;
}
bounds.X += size.Width;
}
return false;
}
void IntersectsBody( int widgetX, int widgetY ) {
widgetY -= elements[0].TitleSize.Height;
widgetX /= elementSize.Width; widgetY /= elementSize.Height;
Element e = elements[selectedIndex];
int index = widgetY * e.ItemsPerRow + widgetX;
if( index < e.Contents.Length ) {
if( selectedIndex == 0 ) {
parent.AppendChar( e.Contents[index * e.CharsPerItem] );
parent.AppendChar( e.Contents[index * e.CharsPerItem + 1] );
} else {
parent.AppendChar( e.Contents[index] );
}
}
}
public override void Dispose() {
graphicsApi.DeleteTexture( ref chatInputTexture );

View File

@ -21,6 +21,7 @@ namespace ClassicalSharp {
DrawTextArgs args = new DrawTextArgs( "_", boldFont, false );
defaultHeight = game.Drawer2D.MeasureChatSize( ref args ).Height;
Height = defaultHeight;
//altText = new AltTextInputWidget( game, font, boldFont, this );
}
Texture chatInputTexture, caretTexture;
@ -45,7 +46,6 @@ namespace ClassicalSharp {
int maxWidth = 0;
public override void Init() {
//altText = new AltTextInputWidget( game, font, boldFont, this );
//altText.Init();
X = 5;
DrawTextArgs args = new DrawTextArgs( "_", boldFont, false );
@ -131,13 +131,14 @@ namespace ClassicalSharp {
Y = game.Height - Height - YOffset;
chatInputTexture.Y1 = Y;
caretTexture.Y1 += Y;
Width = size.Width;
Width = size.Width;
}
public override void Dispose() {
graphicsApi.DeleteTexture( ref caretTexture );
graphicsApi.DeleteTexture( ref chatInputTexture );
//altText.Dispose();
//if( altText != null )
// altText.Dispose();
}
public override void MoveTo( int newX, int newY ) {
@ -205,6 +206,7 @@ namespace ClassicalSharp {
if( chatInputText.Length + text.Length > len ) {
text = text.Substring( 0, len - chatInputText.Length );
}
if( text == "" ) return;
if( caretPos == -1 ) {
chatInputText.InsertAt( chatInputText.Length, text );
@ -216,5 +218,19 @@ namespace ClassicalSharp {
Dispose();
Init();
}
public void AppendChar( char c ) {
if( chatInputText.Length == len ) return;
if( caretPos == -1 ) {
chatInputText.InsertAt( chatInputText.Length, c );
} else {
chatInputText.InsertAt( caretPos, c );
caretPos++;
if( caretPos >= chatInputText.Length ) caretPos = -1;
}
Dispose();
Init();
}
}
}

View File

@ -105,6 +105,7 @@
<Compile Include="2D\Screens\WarningScreen.cs" />
<Compile Include="2D\Texture.cs" />
<Compile Include="2D\Widgets\BlockHotbarWidget.cs" />
<Compile Include="2D\Widgets\Chat\AltTextInputWidget.Types.cs" />
<Compile Include="2D\Widgets\Chat\ChatTextWidget.cs" />
<Compile Include="2D\Widgets\Chat\AltTextInputWidget.cs" />
<Compile Include="2D\Widgets\Chat\TextGroupWidget.cs" />

View File

@ -40,8 +40,8 @@ namespace ClassicalSharp {
FastColour col = FastColour.White;
for( int dx = -extent; dx <= extent; dx++ ) {
for( int dz = -extent; dz <= extent; dz++ ) {
int rainY = Math.Max( pos.Y, GetRainHeight( pos.X + dx, pos.Z + dz ) + 1 );
int height = Math.Min( 20 - (rainY - pos.Y), 20 );
float rainY = GetRainHeight( pos.X + dx, pos.Z + dz );
float height = Math.Max( game.Map.Height, pos.Y + 64 ) - rainY;
if( height <= 0 ) continue;
col.A = (byte)Math.Max( 0, AlphaAt( dx * dx + dz * dz ) );
@ -64,9 +64,10 @@ namespace ClassicalSharp {
return 0.05f * x * x - 7 * x + 178;
}
void MakeRainForSquare( int x, int y, int height, int z, FastColour col, ref int index ) {
float v1 = vOffset + (z & 0x01) * 0.5f - (x & 0x0F) * 0.0625f;
float v2 = height / 6f + v1;
void MakeRainForSquare( int x, float y, float height, int z, FastColour col, ref int index ) {
float worldV = vOffset + (z & 1) / 2f - (x & 0x0F) / 16f;
float v1 = y / 6f + worldV;
float v2 = (y + height) / 6f + worldV;
vertices[index++] = new VertexPos3fTex2fCol4b( x, y, z, 0, v2, col );
vertices[index++] = new VertexPos3fTex2fCol4b( x, y + height, z, 0, v1, col );
@ -107,11 +108,12 @@ namespace ClassicalSharp {
graphics.DeleteDynamicVb( weatherVb );
}
int GetRainHeight( int x, int z ) {
if( x < 0 || z < 0 || x >= width || z >= length ) return map.EdgeHeight - 1;
int index = ( x * length ) + z;
float GetRainHeight( int x, int z ) {
if( x < 0 || z < 0 || x >= width || z >= length ) return map.EdgeHeight;
int index = (x * length) + z;
int height = heightmap[index];
return height == short.MaxValue ? CalcHeightAt( x, maxY, z, index ) : height;
int y = height == short.MaxValue ? CalcHeightAt( x, maxY, z, index ) : height;
return y + game.BlockInfo.Height[map.GetBlock( x, y, z )];
}
int CalcHeightAt( int x, int maxY, int z, int index ) {

View File

@ -16,10 +16,14 @@ namespace ClassicalSharp.Selections {
Colour = col;
}
public void Render( double delta, VertexPos3fCol4b[] vertices, VertexPos3fCol4b[] lineVertices,
public void Render( double delta, Vector3 cameraPos, VertexPos3fCol4b[] vertices, VertexPos3fCol4b[] lineVertices,
ref int index, ref int lineIndex ) {
Vector3 p1 = (Vector3)Min + new Vector3( 1/16f, 1/16f, 1/16f );
Vector3 p2 = (Vector3)Max - new Vector3( 1/16f, 1/16f, 1/16f );
float dist = Math.Min( Utils.DistanceSquared( (Vector3)Min, cameraPos ),
Utils.DistanceSquared( (Vector3)Max, cameraPos ) );
float offset = dist < 32 * 32 ? 1/32f : 1/16f;
Vector3 p1 = (Vector3)Min + new Vector3( offset );
Vector3 p2 = (Vector3)Max - new Vector3( offset );
FastColour col = Colour;
YQuad( vertices, ref index, p1.X, p1.Z, p2.X, p2.Z, p1.Y, col ); // bottom

View File

@ -43,7 +43,7 @@ namespace ClassicalSharp.Selections {
// TODO: Proper selection box sorting. But this is very difficult because
// we can have boxes within boxes, intersecting boxes, etc. Probably not worth it.
comparer.pos = player.Position;
comparer.pos = game.Camera.GetCameraPos( player.EyePosition );
selections.Sort( comparer );
if( vertices == null )
InitData(); // lazy init as most servers don't use this.
@ -51,7 +51,7 @@ namespace ClassicalSharp.Selections {
int index = 0, lineIndex = 0;
for( int i = 0; i < selections.Count; i++ ) {
SelectionBox box = selections[i];
box.Render( delta, vertices, lineVertices, ref index, ref lineIndex );
box.Render( delta, comparer.pos, vertices, lineVertices, ref index, ref lineIndex );
}
Graphics.SetBatchFormat( VertexFormat.Pos3fCol4b );

View File

@ -37,27 +37,23 @@ namespace OpenTK {
public float Z;
public Vector3(float x, float y, float z) {
X = x;
Y = y;
Z = z;
X = x; Y = y; Z = z;
}
public Vector3(float value) {
X = value; Y = value; Z = value;
}
public Vector3(Vector2 v) {
X = v.X;
Y = v.Y;
Z = 0.0f;
X = v.X; Y = v.Y; Z = 0.0f;
}
public Vector3(Vector3 v) {
X = v.X;
Y = v.Y;
Z = v.Z;
X = v.X; Y = v.Y; Z = v.Z;
}
public Vector3(Vector4 v) {
X = v.X;
Y = v.Y;
Z = v.Z;
X = v.X; Y = v.Y; Z = v.Z;
}
public float Length {