mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-14 10:05:44 -04:00
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:
parent
c5a1f5a27e
commit
cc0dd16c42
@ -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);
|
||||
|
@ -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 ),
|
||||
|
107
ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs
Normal file
107
ClassicalSharp/2D/Widgets/Chat/AltTextInputWidget.Types.cs
Normal 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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 );
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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" />
|
||||
|
@ -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 ) {
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user