mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 10:35:11 -04:00
More physics (still to go: saplings)
This commit is contained in:
parent
808d66ea6c
commit
6c69baeb38
@ -366,9 +366,9 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateBlock( int x, int y, int z, byte block ) {
|
public void UpdateBlock( int x, int y, int z, byte block ) {
|
||||||
int oldHeight = Map.GetLightHeight( x, z );
|
int oldHeight = Map.GetLightHeight( x, z ) + 1;
|
||||||
Map.SetBlock( x, y, z, block );
|
Map.SetBlock( x, y, z, block );
|
||||||
int newHeight = Map.GetLightHeight( x, z );
|
int newHeight = Map.GetLightHeight( x, z ) + 1;
|
||||||
MapRenderer.RedrawBlock( x, y, z, block, oldHeight, newHeight );
|
MapRenderer.RedrawBlock( x, y, z, block, oldHeight, newHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ namespace ClassicalSharp {
|
|||||||
byte block = mapData[mapIndex];
|
byte block = mapData[mapIndex];
|
||||||
if( info.BlocksLight[block] ) {
|
if( info.BlocksLight[block] ) {
|
||||||
heightmap[index] = (short)( y - 1 );
|
heightmap[index] = (short)( y - 1 );
|
||||||
return y;
|
return y - 1;
|
||||||
}
|
}
|
||||||
mapIndex -= oneY;
|
mapIndex -= oneY;
|
||||||
}
|
}
|
||||||
|
@ -149,19 +149,15 @@ namespace ClassicalSharp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void RedrawBlock( int x, int y, int z, byte block, int oldHeight, int newHeight ) {
|
public void RedrawBlock( int x, int y, int z, byte block, int oldHeight, int newHeight ) {
|
||||||
int cx = x >> 4;
|
int cx = x >> 4, bX = x & 0x0F;
|
||||||
int cy = y >> 4;
|
int cy = y >> 4, bY = y & 0x0F;
|
||||||
int cz = z >> 4;
|
int cz = z >> 4, bZ = z & 0x0F;
|
||||||
// NOTE: It's a lot faster to only update the chunks that are affected by the change in shadows,
|
// NOTE: It's a lot faster to only update the chunks that are affected by the change in shadows,
|
||||||
// rather than the entire column.
|
// rather than the entire column.
|
||||||
int newLightcy = newHeight == -1 ? 0 : newHeight >> 4;
|
int newLightcy = newHeight < 0 ? 0 : newHeight >> 4;
|
||||||
int oldLightcy = oldHeight == -1 ? 0 : oldHeight >> 4;
|
int oldLightcy = oldHeight < 0 ? 0 : oldHeight >> 4;
|
||||||
|
|
||||||
ResetChunkAndBelow( cx, cy, cz, newLightcy, oldLightcy );
|
ResetChunkAndBelow( cx, cy, cz, newLightcy, oldLightcy );
|
||||||
int bX = x & 0x0F; // % 16
|
|
||||||
int bY = y & 0x0F;
|
|
||||||
int bZ = z & 0x0F;
|
|
||||||
|
|
||||||
if( bX == 0 && cx > 0 ) ResetChunkAndBelow( cx - 1, cy, cz, newLightcy, oldLightcy );
|
if( bX == 0 && cx > 0 ) ResetChunkAndBelow( cx - 1, cy, cz, newLightcy, oldLightcy );
|
||||||
if( bY == 0 && cy > 0 ) ResetChunkAndBelow( cx, cy - 1, cz, newLightcy, oldLightcy );
|
if( bY == 0 && cy > 0 ) ResetChunkAndBelow( cx, cy - 1, cz, newLightcy, oldLightcy );
|
||||||
if( bZ == 0 && cz > 0 ) ResetChunkAndBelow( cx, cy, cz - 1, newLightcy, oldLightcy );
|
if( bZ == 0 && cz > 0 ) ResetChunkAndBelow( cx, cy, cz - 1, newLightcy, oldLightcy );
|
||||||
|
@ -9,7 +9,7 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
Game game;
|
Game game;
|
||||||
public Map map;
|
public Map map;
|
||||||
BlockInfo info;
|
BlockInfo info;
|
||||||
int width, length, height, oneY;
|
int width, length, height, oneY, volume;
|
||||||
|
|
||||||
const uint tickMask = 0xF8000000;
|
const uint tickMask = 0xF8000000;
|
||||||
const uint posMask = 0x07FFFFFF;
|
const uint posMask = 0x07FFFFFF;
|
||||||
@ -50,10 +50,15 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int tickCount = 0;
|
||||||
public void Tick() {
|
public void Tick() {
|
||||||
|
//if( (tickCount % 5) == 0 ) {
|
||||||
TickLava();
|
TickLava();
|
||||||
TickWater();
|
TickWater();
|
||||||
TickFalling();
|
TickFalling();
|
||||||
|
//}
|
||||||
|
tickCount++;
|
||||||
|
TickRandomBlocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnBlockPlaced( int x, int y, int z, byte block ) {
|
public void OnBlockPlaced( int x, int y, int z, byte block ) {
|
||||||
@ -76,8 +81,72 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
length = map.Length;
|
length = map.Length;
|
||||||
height = map.Height;
|
height = map.Height;
|
||||||
oneY = height * width;
|
oneY = height * width;
|
||||||
|
volume = height * width * length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region General
|
||||||
|
// TODO: tree growing
|
||||||
|
|
||||||
|
void TickRandomBlocks() {
|
||||||
|
for( int y = 0; y < height; y += 16 ) {
|
||||||
|
for( int z = 0; z < length; z += 16 ) {
|
||||||
|
for( int x = 0; x < width; x += 16 ) {
|
||||||
|
int lo = (y * length + z) * width + x;
|
||||||
|
int hi = ((y + 15) * length + (z + 15)) * width + (x + 15 );
|
||||||
|
HandleBlock( rnd.Next( lo, hi ) );
|
||||||
|
HandleBlock( rnd.Next( lo, hi ) );
|
||||||
|
HandleBlock( rnd.Next( lo, hi ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleBlock( int posIndex ) {
|
||||||
|
int x = posIndex % width;
|
||||||
|
int y = posIndex / oneY; // posIndex / (width * length)
|
||||||
|
int z = (posIndex / width) % length;
|
||||||
|
byte block = map.mapData[posIndex];
|
||||||
|
|
||||||
|
switch( block ) {
|
||||||
|
case (byte)Block.Dirt:
|
||||||
|
if( y > map.GetLightHeight( x, z ) )
|
||||||
|
game.UpdateBlock( x, y, z, (byte)Block.Grass );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (byte)Block.Grass:
|
||||||
|
if( y <= map.GetLightHeight( x, z ) ) {
|
||||||
|
game.UpdateBlock( x, y, z, (byte)Block.Dirt );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (byte)Block.Dandelion:
|
||||||
|
case (byte)Block.Rose:
|
||||||
|
case (byte)Block.BrownMushroom:
|
||||||
|
case (byte)Block.RedMushroom:
|
||||||
|
if( y <= map.GetLightHeight( x, z ) )
|
||||||
|
game.UpdateBlock( x, y, z, (byte)Block.Air );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (byte)Block.Sapling:
|
||||||
|
game.UpdateBlock( x, y, z, (byte)Block.ForestGreenWool );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (byte)Block.Sand:
|
||||||
|
case (byte)Block.Gravel:
|
||||||
|
if( y > 0 ) PropagateFalling( posIndex, x, y, z, block, 0 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (byte)Block.Lava:
|
||||||
|
HandleLava( posIndex, x, y, z );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (byte)Block.Water:
|
||||||
|
HandleWater( posIndex, x, y, z );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Lava
|
#region Lava
|
||||||
|
|
||||||
Queue<uint> Lava = new Queue<uint>();
|
Queue<uint> Lava = new Queue<uint>();
|
||||||
@ -94,16 +163,19 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
int x = posIndex % width;
|
int x = posIndex % width;
|
||||||
int y = posIndex / oneY; // posIndex / (width * length)
|
int y = posIndex / oneY; // posIndex / (width * length)
|
||||||
int z = (posIndex / width) % length;
|
int z = (posIndex / width) % length;
|
||||||
|
HandleLava( posIndex, x, y, z );
|
||||||
if( x > 0 ) PropagateLava( posIndex - 1, x - 1, y, z );
|
|
||||||
if( x < width - 1 ) PropagateLava( posIndex + 1, x + 1, y, z );
|
|
||||||
if( z > 0 ) PropagateLava( posIndex - width, x, y, z - 1 );
|
|
||||||
if( z < length - 1 ) PropagateLava( posIndex + width, x, y, z + 1 );
|
|
||||||
if( y > 0 ) PropagateLava( posIndex - oneY, x, y - 1, z );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleLava( int posIndex, int x, int y, int z ) {
|
||||||
|
if( x > 0 ) PropagateLava( posIndex - 1, x - 1, y, z );
|
||||||
|
if( x < width - 1 ) PropagateLava( posIndex + 1, x + 1, y, z );
|
||||||
|
if( z > 0 ) PropagateLava( posIndex - width, x, y, z - 1 );
|
||||||
|
if( z < length - 1 ) PropagateLava( posIndex + width, x, y, z + 1 );
|
||||||
|
if( y > 0 ) PropagateLava( posIndex - oneY, x, y - 1, z );
|
||||||
|
}
|
||||||
|
|
||||||
void PropagateLava( int posIndex, int x, int y, int z ) {
|
void PropagateLava( int posIndex, int x, int y, int z ) {
|
||||||
byte block = map.mapData[posIndex];
|
byte block = map.mapData[posIndex];
|
||||||
if( block == (byte)Block.Water || block == (byte)Block.StillWater ) {
|
if( block == (byte)Block.Water || block == (byte)Block.StillWater ) {
|
||||||
@ -132,16 +204,19 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
int x = posIndex % width;
|
int x = posIndex % width;
|
||||||
int y = posIndex / oneY; // posIndex / (width * length)
|
int y = posIndex / oneY; // posIndex / (width * length)
|
||||||
int z = (posIndex / width) % length;
|
int z = (posIndex / width) % length;
|
||||||
|
HandleWater( posIndex, x, y, z );
|
||||||
if( x > 0 ) PropagateWater( posIndex - 1, x - 1, y, z );
|
|
||||||
if( x < width - 1 ) PropagateWater( posIndex + 1, x + 1, y, z );
|
|
||||||
if( z > 0 ) PropagateWater( posIndex - width, x, y, z - 1 );
|
|
||||||
if( z < length - 1 ) PropagateWater( posIndex + width, x, y, z + 1 );
|
|
||||||
if( y > 0 ) PropagateWater( posIndex - oneY, x, y - 1, z );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleWater( int posIndex, int x, int y, int z ) {
|
||||||
|
if( x > 0 ) PropagateWater( posIndex - 1, x - 1, y, z );
|
||||||
|
if( x < width - 1 ) PropagateWater( posIndex + 1, x + 1, y, z );
|
||||||
|
if( z > 0 ) PropagateWater( posIndex - width, x, y, z - 1 );
|
||||||
|
if( z < length - 1 ) PropagateWater( posIndex + width, x, y, z + 1 );
|
||||||
|
if( y > 0 ) PropagateWater( posIndex - oneY, x, y - 1, z );
|
||||||
|
}
|
||||||
|
|
||||||
void PropagateWater( int posIndex, int x, int y, int z ) {
|
void PropagateWater( int posIndex, int x, int y, int z ) {
|
||||||
byte block = map.mapData[posIndex];
|
byte block = map.mapData[posIndex];
|
||||||
if( block == (byte)Block.Lava || block == (byte)Block.StillLava ) {
|
if( block == (byte)Block.Lava || block == (byte)Block.StillLava ) {
|
||||||
@ -154,6 +229,52 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Sand/Gravel
|
||||||
|
|
||||||
|
Queue<uint> Falling = new Queue<uint>();
|
||||||
|
const uint defFallingTick = 2u << tickShift;
|
||||||
|
|
||||||
|
void TickFalling() {
|
||||||
|
int count = Falling.Count;
|
||||||
|
for( int i = 0; i < count; i++ ) {
|
||||||
|
int posIndex, flags;
|
||||||
|
if( CheckItem( Falling, 0x2, out posIndex, out flags ) ) {
|
||||||
|
byte block = map.mapData[posIndex];
|
||||||
|
if( !(block == (byte)Block.Sand || block == (byte)Block.Gravel ) ) continue;
|
||||||
|
|
||||||
|
int x = posIndex % width;
|
||||||
|
int y = posIndex / oneY; // posIndex / (width * length)
|
||||||
|
int z = (posIndex / width) % length;
|
||||||
|
if( y > 0 ) PropagateFalling( posIndex, x, y, z, block, flags );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PropagateFalling( int posIndex, int x, int y, int z, byte block, int flags ) {
|
||||||
|
byte newBlock = map.mapData[posIndex - oneY];
|
||||||
|
if( newBlock == 0 || info.IsLiquid[newBlock] ) {
|
||||||
|
uint newFlags = MakeFallingFlags( newBlock ) << tickShift;
|
||||||
|
Falling.Enqueue( newFlags | (uint)(posIndex - oneY) );
|
||||||
|
|
||||||
|
game.UpdateBlock( x, y, z, oldBlock[flags >> 2] );
|
||||||
|
game.UpdateBlock( x, y - 1, z, block );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] oldBlock = new byte[] { (byte)Block.Air, (byte)Block.StillWater,
|
||||||
|
(byte)Block.Water, (byte)Block.StillLava, (Byte)Block.Lava };
|
||||||
|
static uint MakeFallingFlags( byte above ) {
|
||||||
|
byte flags = 2;
|
||||||
|
if( above == (byte)Block.StillWater ) flags |= 0x04; // 1
|
||||||
|
else if( above == (byte)Block.Water ) flags |= 0x08; // 2
|
||||||
|
else if( above == (byte)Block.StillLava ) flags |= 0x0C; // 3
|
||||||
|
else if( above == (byte)Block.Lava ) flags |= 0x10; // 4
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region TNT
|
#region TNT
|
||||||
|
|
||||||
Vector3[] rayDirs;
|
Vector3[] rayDirs;
|
||||||
@ -226,57 +347,5 @@ namespace ClassicalSharp.Singleplayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Sapling
|
|
||||||
// TODO: tree growing
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Grass
|
|
||||||
// TODO: grass growing
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Sand/Gravel
|
|
||||||
|
|
||||||
Queue<uint> Falling = new Queue<uint>();
|
|
||||||
const uint defFallingTick = 2u << tickShift;
|
|
||||||
|
|
||||||
void TickFalling() {
|
|
||||||
int count = Falling.Count;
|
|
||||||
for( int i = 0; i < count; i++ ) {
|
|
||||||
int posIndex, flags;
|
|
||||||
if( CheckItem( Falling, 0x2, out posIndex, out flags ) ) {
|
|
||||||
byte block = map.mapData[posIndex];
|
|
||||||
if( !(block == (byte)Block.Sand || block == (byte)Block.Gravel ) ) continue;
|
|
||||||
|
|
||||||
int x = posIndex % width;
|
|
||||||
int y = posIndex / oneY; // posIndex / (width * length)
|
|
||||||
int z = (posIndex / width) % length;
|
|
||||||
if( y > 0 ) PropagateFalling( posIndex - oneY, x, y - 1, z, block, flags );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PropagateFalling( int posIndex, int x, int y, int z, byte block, int flags ) {
|
|
||||||
byte newBlock = map.mapData[posIndex];
|
|
||||||
if( newBlock == 0 || info.IsLiquid[newBlock] ) {
|
|
||||||
uint newFlags = MakeFallingFlags( newBlock ) << tickShift;
|
|
||||||
Falling.Enqueue( newFlags | (uint)posIndex );
|
|
||||||
game.UpdateBlock( x, y, z, oldBlock[flags >> 2] );
|
|
||||||
game.UpdateBlock( x, y - 1, z, block );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static byte[] oldBlock = new byte[] { (byte)Block.Air, (byte)Block.StillWater,
|
|
||||||
(byte)Block.Water, (byte)Block.StillLava, (Byte)Block.Lava };
|
|
||||||
static uint MakeFallingFlags( byte above ) {
|
|
||||||
byte flags = 2;
|
|
||||||
if( above == (byte)Block.StillWater ) flags |= 0x04; // 1
|
|
||||||
else if( above == (byte)Block.Water ) flags |= 0x08; // 2
|
|
||||||
else if( above == (byte)Block.StillLava ) flags |= 0x0C; // 3
|
|
||||||
else if( above == (byte)Block.Lava ) flags |= 0x10; // 4
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -98,6 +98,7 @@
|
|||||||
<Compile Include="Platform\MacOS\MacOSException.cs" />
|
<Compile Include="Platform\MacOS\MacOSException.cs" />
|
||||||
<Compile Include="Platform\MacOS\MacOSKeyMap.cs" />
|
<Compile Include="Platform\MacOS\MacOSKeyMap.cs" />
|
||||||
<Compile Include="Platform\MacOS\QuartzDisplayDeviceDriver.cs" />
|
<Compile Include="Platform\MacOS\QuartzDisplayDeviceDriver.cs" />
|
||||||
|
<Compile Include="Platform\Minimal.cs" />
|
||||||
<Compile Include="Platform\PlatformException.cs" />
|
<Compile Include="Platform\PlatformException.cs" />
|
||||||
<Compile Include="Platform\Windows\API.cs" />
|
<Compile Include="Platform\Windows\API.cs" />
|
||||||
<Compile Include="Platform\Windows\Wgl.cs" />
|
<Compile Include="Platform\Windows\Wgl.cs" />
|
||||||
|
264
OpenTK/Platform/Minimal.cs
Normal file
264
OpenTK/Platform/Minimal.cs
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
#if OPENTK_MINIMAL
|
||||||
|
using System;
|
||||||
|
// These classes fill in for missing Rectangle, Point, and Size implementations
|
||||||
|
|
||||||
|
namespace System.Drawing {
|
||||||
|
|
||||||
|
public struct Rectangle {
|
||||||
|
|
||||||
|
public static readonly Rectangle Empty = default(Rectangle);
|
||||||
|
public int X, Y;
|
||||||
|
public int Width, Height;
|
||||||
|
|
||||||
|
public Point Location {
|
||||||
|
get { return new Point( X, Y ); }
|
||||||
|
set { X = value.X; Y = value.Y; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Size Size {
|
||||||
|
get { return new Size( Width, Height ); }
|
||||||
|
set { Width = value.Width; Height = value.Height; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Left {
|
||||||
|
get { return X; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Top {
|
||||||
|
get { return Y; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Right {
|
||||||
|
get { return X + Width; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Bottom {
|
||||||
|
get { return Y + Height; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty {
|
||||||
|
get { return Height == 0 && Width == 0 && X == 0 && Y == 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rectangle( int x, int y, int width, int height ) {
|
||||||
|
X = x; Y = y;
|
||||||
|
Width = width; Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rectangle( Point loc, Size size ) {
|
||||||
|
X = loc.X; Y = loc.Y;
|
||||||
|
Width = size.Width; Height = size.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Rectangle FromLTRB( int left, int top, int right, int bottom ) {
|
||||||
|
return new Rectangle( left, top, right - left, bottom - top );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals( object obj ) {
|
||||||
|
return (obj is Rectangle) && Equals( (Rectangle)obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals( Rectangle other ) {
|
||||||
|
return X == other.X && Y == other.Y && Width == other.Width && Height == other.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return 1000000007 * X + 1000000009 * Y +
|
||||||
|
1000000021 * Width + 1000000033 * Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator == ( Rectangle lhs, Rectangle rhs ) {
|
||||||
|
return lhs.Equals( rhs );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator != ( Rectangle lhs, Rectangle rhs ) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains(int x, int y) {
|
||||||
|
return X <= x && x < X + Width && Y <= y && y < Y + Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains( Point pt ) {
|
||||||
|
return Contains( pt.X, pt.Y );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains( Rectangle rect ) {
|
||||||
|
return X <= rect.X && rect.X + rect.Width <= X + Width && Y <= rect.Y && rect.Y + rect.Height <= Y + Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return X + ", " + Y + " : " + Width + "," + Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Size {
|
||||||
|
|
||||||
|
public static readonly Size Empty = default(Size);
|
||||||
|
public int Width, Height;
|
||||||
|
|
||||||
|
public bool IsEmpty {
|
||||||
|
get { return Width == 0 && Height == 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Size( Point point ) {
|
||||||
|
Width = point.X; Height = point.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Size( int width, int height ) {
|
||||||
|
Width = width; Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Size Ceiling( SizeF value ) {
|
||||||
|
return new Size( (int)Math.Ceiling( value.Width ), (int)Math.Ceiling( value.Height ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals( object obj ) {
|
||||||
|
return (obj is Size) && Equals( (Size)obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals( Size other ) {
|
||||||
|
return Width == other.Width && Height == other.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return 1000000007 * Width + 1000000009 * Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator == ( Size lhs, Size rhs ) {
|
||||||
|
return lhs.Width == rhs.Width && lhs.Height == rhs.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator != ( Size lhs, Size rhs ) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return Width + "," + Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct SizeF {
|
||||||
|
|
||||||
|
public static readonly SizeF Empty = default(SizeF);
|
||||||
|
public float Width, Height;
|
||||||
|
|
||||||
|
public bool IsEmpty {
|
||||||
|
get { return Width == 0 && Height == 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public SizeF( float width, float height ) {
|
||||||
|
Width = width; Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals( object obj ) {
|
||||||
|
return (obj is SizeF) && Equals( (SizeF)obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals( SizeF other ) {
|
||||||
|
return Width == other.Width && Height == other.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return 1000000007 * Width.GetHashCode() +
|
||||||
|
1000000009 * Height.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator == ( SizeF lhs, SizeF rhs ) {
|
||||||
|
return lhs.Width == rhs.Width && lhs.Height == rhs.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator != ( SizeF lhs, SizeF rhs ) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return Width + "," + Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Point {
|
||||||
|
|
||||||
|
public static readonly Point Empty = default(Point);
|
||||||
|
public int X, Y;
|
||||||
|
|
||||||
|
public bool IsEmpty {
|
||||||
|
get { return X == 0 && Y == 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point( Size size ) {
|
||||||
|
X = size.Width; Y = size.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point( int x, int y ) {
|
||||||
|
X = x; Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals( object obj ) {
|
||||||
|
return (obj is Point) && Equals( (Point)obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals( Point other ) {
|
||||||
|
return X == other.X && Y == other.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return 1000000007 * X + 1000000009 * Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator == ( Point lhs, Point rhs ) {
|
||||||
|
return lhs.X == rhs.X && lhs.Y == rhs.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator != ( Point lhs, Point rhs ) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return X + "," + Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Color {
|
||||||
|
public byte R, G, B, A;
|
||||||
|
|
||||||
|
public Color( int r, int g, int b, int a ) {
|
||||||
|
A = (byte)a;
|
||||||
|
R = (byte)r;
|
||||||
|
G = (byte)g;
|
||||||
|
B = (byte)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color( int r, int g, int b ) {
|
||||||
|
A = 255;
|
||||||
|
R = (byte)r;
|
||||||
|
G = (byte)g;
|
||||||
|
B = (byte)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals( object obj ) {
|
||||||
|
return ( obj is Color ) && Equals( (Color)obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals( Color other ) {
|
||||||
|
return A == other.A && R == other.R && G == other.G && B == other.B;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() {
|
||||||
|
return A << 24 | R << 16 | G << 8 | B;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator == ( Color left, Color right ) {
|
||||||
|
return left.Equals( right );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator != ( Color left, Color right ) {
|
||||||
|
return !left.Equals( right );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return R + ", " + G + ", " + B + " : " + A;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user