mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 17:47:12 -04:00
Fix block model on AMD, fix /client gpu info crashing client, add support for default minecraft font.
This commit is contained in:
parent
4f4b6e2a2f
commit
c7ebbf985b
@ -9,32 +9,30 @@ namespace ClassicalSharp {
|
||||
// NOTE: This drawer is still a big work in progress and not close to done
|
||||
// TODO: proper shadow colour
|
||||
// TODO: italic and bold
|
||||
Bitmap realBmp;
|
||||
Bitmap fontBmp;
|
||||
FastBitmap fontPixels;
|
||||
int boxSize;
|
||||
public GdiPlusDrawerMCFont( IGraphicsApi graphics ) : base( graphics ) {
|
||||
realBmp = new Bitmap( "default.png" );
|
||||
fontBmp = new Bitmap( "default.png" );
|
||||
boxSize = fontBmp.Width / 16;
|
||||
fontPixels = new FastBitmap( fontBmp, true );
|
||||
CalculateTextWidths();
|
||||
}
|
||||
|
||||
int[] widths = new int[256];
|
||||
unsafe void CalculateTextWidths() {
|
||||
using( FastBitmap fastBmp = new FastBitmap( realBmp, true ) ) {
|
||||
for( int i = 0; i < 256; i++ ) {
|
||||
int tileX = (i & 0x0F) * 8;
|
||||
int tileY = (i >> 4) * 8;
|
||||
MakeTile( fastBmp, i, tileX, tileY );
|
||||
}
|
||||
}
|
||||
widths[(int)' '] = 4;
|
||||
void CalculateTextWidths() {
|
||||
for( int i = 0; i < 256; i++ )
|
||||
MakeTile( i, (i & 0x0F) * boxSize, (i >> 4) * boxSize );
|
||||
widths[(int)' '] = boxSize / 2;
|
||||
}
|
||||
|
||||
unsafe void MakeTile( FastBitmap fastBmp, int i, int tileX, int tileY ) {
|
||||
for( int x = 7; x >= 0; x-- ) {
|
||||
for( int y = 0; y < 8; y++ ) {
|
||||
uint pixel = (uint)fastBmp.GetRowPtr( tileY + y )[tileX + x];
|
||||
unsafe void MakeTile( int i, int tileX, int tileY ) {
|
||||
for( int x = boxSize - 1; x >= 0; x-- ) {
|
||||
for( int y = 0; y < boxSize; y++ ) {
|
||||
uint pixel = (uint)fontPixels.GetRowPtr( tileY + y )[tileX + x];
|
||||
uint a = pixel >> 24;
|
||||
if( a >= 127 ) {
|
||||
widths[i] = x + 1;
|
||||
Console.WriteLine( widths[i] );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -47,7 +45,7 @@ namespace ClassicalSharp {
|
||||
GetTextParts( args.Text );
|
||||
|
||||
if( args.UseShadow ) {
|
||||
int shadowX = x + 1, shadowY = y + 1;
|
||||
int shadowX = x + 2, shadowY = y + 2;
|
||||
for( int i = 0; i < parts.Count; i++ ) {
|
||||
TextPart part = parts[i];
|
||||
part.TextColour = FastColour.Black;
|
||||
@ -61,45 +59,31 @@ namespace ClassicalSharp {
|
||||
}
|
||||
}
|
||||
|
||||
void DrawPart( ref int x, int y, float point, TextPart part ) {
|
||||
unsafe void DrawPart( ref int x, int y, float point, TextPart part ) {
|
||||
string text = part.Text;
|
||||
foreach( char c in text ) {
|
||||
int coords = (int)c;
|
||||
int srcX = (coords & 0x0F) * 8;
|
||||
int srcY = (coords >> 4) * 8;
|
||||
int coords = ConvertToCP437( c );
|
||||
int srcX = (coords & 0x0F) * boxSize;
|
||||
int srcY = (coords >> 4) * boxSize;
|
||||
|
||||
for( int yy = 0; yy < 8; yy++ ) {
|
||||
for( int xx = 0; xx < widths[coords]; xx++ ) {
|
||||
FastColour col = realBmp.GetPixel( srcX + xx, srcY + yy );
|
||||
int srcWidth = widths[coords], dstWidth = PtToPx( point, srcWidth );
|
||||
int srcHeight = boxSize, dstHeight = PtToPx( point, srcHeight );
|
||||
for( int yy = 0; yy < dstHeight; yy++ ) {
|
||||
int fontY = srcY + yy * srcHeight / dstHeight;
|
||||
int* fontRow = fontPixels.GetRowPtr( fontY );
|
||||
|
||||
for( int xx = 0; xx < dstWidth; xx++ ) {
|
||||
int fontX = srcX + xx * srcWidth / dstWidth;
|
||||
FastColour col = new FastColour( fontRow[fontX] );
|
||||
if( col.A < 127 ) continue;
|
||||
|
||||
col.R = (byte)(col.R * part.TextColour.R / 255);
|
||||
col.G = (byte)(col.G * part.TextColour.G / 255);
|
||||
col.B = (byte)(col.B * part.TextColour.B / 255);
|
||||
|
||||
col.B = (byte)(col.B * part.TextColour.B / 255);
|
||||
curBmp.SetPixel( x + xx, y + yy, col );
|
||||
}
|
||||
}
|
||||
x += widths[coords] + 1;
|
||||
/*int rawWidth = widths[coords] + 1;
|
||||
int rawHeight = 8;
|
||||
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
g.DrawImage( realBmp,
|
||||
new Rectangle( x, y, PtToPx( point, rawWidth ), PtToPx( point, rawHeight ) ),
|
||||
new Rectangle( srcX, srcY, 8, 8 ),
|
||||
GraphicsUnit.Pixel );
|
||||
|
||||
for( int yy = 0; yy < PtToPx( point, rawHeight ); yy++ ) {
|
||||
for( int xx = 0; xx < PtToPx( point, rawWidth ); xx++ ) {
|
||||
FastColour col = curBmp.GetPixel( x + xx, y + yy );
|
||||
if( col.A < 127 ) continue;
|
||||
col.R = (byte)(col.R * part.TextColour.R / 255);
|
||||
col.G = (byte)(col.G * part.TextColour.G / 255);
|
||||
col.B = (byte)(col.B * part.TextColour.B / 255);
|
||||
|
||||
curBmp.SetPixel( x + xx, y + yy, col );
|
||||
}
|
||||
}
|
||||
x += PtToPx( point, rawWidth );*/
|
||||
x += PtToPx( point, srcWidth + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,31 +94,44 @@ namespace ClassicalSharp {
|
||||
public override Size MeasureSize( ref DrawTextArgs args ) {
|
||||
GetTextParts( args.Text );
|
||||
float point = args.Font.Size;
|
||||
//Size total = new Size( 0, PtToPx( point, 8 ) );
|
||||
Size total = new Size( 0, 8 );
|
||||
Size total = new Size( 0, PtToPx( point, boxSize ) );
|
||||
|
||||
for( int i = 0; i < parts.Count; i++ ) {
|
||||
foreach( char c in parts[i].Text ) {
|
||||
total.Width += widths[(int)c] + 1;//PtToPx( point, widths[(int)c] + 1 );
|
||||
int coords = ConvertToCP437( c );
|
||||
total.Width += PtToPx( point, widths[coords] + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
if( args.UseShadow && parts.Count > 0 ) {
|
||||
total.Width += 1; total.Height += 1;
|
||||
total.Width += 2; total.Height += 2;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
int ConvertToCP437( char c ) {
|
||||
if( c >= ' ' && c <= '~')
|
||||
return (int)c;
|
||||
|
||||
int cIndex = Utils.ControlCharReplacements.IndexOf( c );
|
||||
if( cIndex >= 0 ) return cIndex;
|
||||
int eIndex = Utils.ExtendedCharReplacements.IndexOf( c );
|
||||
if( eIndex >= 0 ) return 127 + eIndex;
|
||||
return (int)'?';
|
||||
}
|
||||
|
||||
int PtToPx( int point ) {
|
||||
return (int)Math.Ceiling( (float)point / 72 * 96 ); // TODO: non 96 dpi?
|
||||
}
|
||||
|
||||
int PtToPx( float point, float value ) {
|
||||
return (int)Math.Ceiling( (value / 8f) * point / 72f * 96f );
|
||||
return (int)Math.Ceiling( (value / boxSize) * point / 72f * 96f );
|
||||
}
|
||||
|
||||
public override void DisposeInstance() {
|
||||
base.DisposeInstance();
|
||||
fontPixels.Dispose();
|
||||
fontBmp.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,6 @@ namespace ClassicalSharp.Commands {
|
||||
foreach( string line in game.Graphics.ApiInfo ) {
|
||||
game.Chat.Add( "&a" + line );
|
||||
}
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,15 +43,15 @@ namespace ClassicalSharp.Model {
|
||||
BlockInfo = game.BlockInfo;
|
||||
|
||||
if( BlockInfo.IsSprite[block] ) {
|
||||
DrawXFace( 0f, TileSide.Right, false );
|
||||
DrawZFace( 0f, TileSide.Back, false );
|
||||
XQuad( 0f, TileSide.Right, false );
|
||||
ZQuad( 0f, TileSide.Back, false );
|
||||
} else {
|
||||
DrawYFace( blockHeight, TileSide.Top );
|
||||
DrawXFace( -0.5f, TileSide.Right, false );
|
||||
DrawXFace( 0.5f, TileSide.Left, true );
|
||||
DrawZFace( -0.5f, TileSide.Front, true );
|
||||
DrawZFace( 0.5f, TileSide.Back, false );
|
||||
DrawYFace( 0f, TileSide.Bottom );
|
||||
YQuad( blockHeight, TileSide.Top );
|
||||
XQuad( -0.5f, TileSide.Right, false );
|
||||
XQuad( 0.5f, TileSide.Left, true );
|
||||
ZQuad( -0.5f, TileSide.Front, true );
|
||||
ZQuad( 0.5f, TileSide.Back, false );
|
||||
YQuad( 0f, TileSide.Bottom );
|
||||
}
|
||||
}
|
||||
float blockHeight;
|
||||
@ -61,9 +61,9 @@ namespace ClassicalSharp.Model {
|
||||
public override void Dispose() {
|
||||
}
|
||||
|
||||
void DrawYFace( float y, int side ) {
|
||||
void YQuad( float y, int side ) {
|
||||
int texId = BlockInfo.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
TextureRec rec = atlas.GetAdjTexRec( texId );
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + y, pos.Z + -0.5f, rec.U1, rec.V1, col );
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + y, pos.Z + -0.5f, rec.U2, rec.V1, col );
|
||||
@ -71,12 +71,11 @@ namespace ClassicalSharp.Model {
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + y, pos.Z + 0.5f, rec.U1, rec.V2, col );
|
||||
}
|
||||
|
||||
void DrawZFace( float z, int side, bool swapU ) {
|
||||
void ZQuad( float z, int side, bool swapU ) {
|
||||
int texId = BlockInfo.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
if( blockHeight != 1 ) {
|
||||
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize;
|
||||
}
|
||||
TextureRec rec = atlas.GetAdjTexRec( texId );
|
||||
if( blockHeight != 1 )
|
||||
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize * (15.99f/16f);
|
||||
if( swapU ) rec.SwapU();
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + -0.5f, pos.Y + 0f, pos.Z + z, rec.U1, rec.V2, col );
|
||||
@ -85,12 +84,11 @@ namespace ClassicalSharp.Model {
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + 0.5f, pos.Y + 0f, pos.Z + z, rec.U2, rec.V2, col );
|
||||
}
|
||||
|
||||
void DrawXFace( float x, int side, bool swapU ) {
|
||||
void XQuad( float x, int side, bool swapU ) {
|
||||
int texId = BlockInfo.GetTextureLoc( block, side );
|
||||
TextureRec rec = atlas.GetTexRec( texId );
|
||||
if( blockHeight != 1 ) {
|
||||
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize;
|
||||
}
|
||||
TextureRec rec = atlas.GetAdjTexRec( texId );
|
||||
if( blockHeight != 1 )
|
||||
rec.V2 = rec.V1 + blockHeight * TerrainAtlas2D.invElementSize * (15.99f/16f);
|
||||
if( swapU ) rec.SwapU();
|
||||
|
||||
cache.vertices[index++] = new VertexPos3fTex2fCol4b( pos.X + x, pos.Y + 0f, pos.Z + -0.5f, rec.U1, rec.V2, col );
|
||||
|
@ -111,19 +111,14 @@ namespace ClassicalSharp {
|
||||
|
||||
// Treat code as an index in code page 437
|
||||
if( code < 0x20 ) {
|
||||
characters[i] = controlCharReplacements[code];
|
||||
characters[i] = Utils.ControlCharReplacements[code];
|
||||
} else if( code < 0x7F ) {
|
||||
characters[i] = (char)code;
|
||||
} else {
|
||||
characters[i] = extendedCharReplacements[code - 0x7F];
|
||||
characters[i] = Utils.ExtendedCharReplacements[code - 0x7F];
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
const string controlCharReplacements = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼";
|
||||
static string extendedCharReplacements = "⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»" +
|
||||
"░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌" +
|
||||
"█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■\u00a0";
|
||||
}
|
||||
}
|
@ -68,6 +68,15 @@ namespace ClassicalSharp {
|
||||
invElementSize, invElementSize, invElementSize );
|
||||
}
|
||||
|
||||
/// <summary> Gets a rectangle that describes the UV coordinates for
|
||||
/// the tile at the specified index, adjusted to work for AMD/ATI cards. </summary>
|
||||
public TextureRec GetAdjTexRec( int index ) {
|
||||
// Adjust coords to be slightly inside - fixes issues with AMD/ATI cards.
|
||||
const float invAdjSize = invElementSize * (15.99f/16f);
|
||||
return new TextureRec( (index & 0x0F) * invElementSize, (index >> 4) *
|
||||
invElementSize, invAdjSize, invAdjSize );
|
||||
}
|
||||
|
||||
/// <summary> Disposes of the underlying atlas bitmap and texture. </summary>
|
||||
public void Dispose() {
|
||||
if( AtlasBitmap != null )
|
||||
|
@ -286,5 +286,13 @@ namespace ClassicalSharp {
|
||||
public static bool IsUrlPrefix( string value ) {
|
||||
return value.StartsWith( "http://" ) || value.StartsWith( "https://" );
|
||||
}
|
||||
|
||||
/// <summary> Conversion for code page 437 characters from index 0 to 31 to unicode. </summary>
|
||||
public const string ControlCharReplacements = "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼";
|
||||
|
||||
/// <summary> Conversion for code page 437 characters from index 127 to 255 to unicode. </summary>
|
||||
public const string ExtendedCharReplacements = "⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»" +
|
||||
"░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌" +
|
||||
"█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■\u00a0";
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user