diff --git a/ClassicalSharp/Blocks/BlockInfo.cs b/ClassicalSharp/Blocks/BlockInfo.cs
index 537fc1b74..9effc243f 100644
--- a/ClassicalSharp/Blocks/BlockInfo.cs
+++ b/ClassicalSharp/Blocks/BlockInfo.cs
@@ -51,9 +51,9 @@ namespace ClassicalSharp {
SetBlockHeight( Block.Snow, 2/16f );
MarkTranslucent( Block.StillWater ); MarkTranslucent( Block.Water );
MarkTranslucent( Block.Ice );
- MarkTransparent( Block.Glass ); MarkTransparent( Block.Leaves );
- MarkTransparent( Block.Slab ); MarkTransparent( Block.Snow );
- MarkTransparent( Block.CobblestoneSlab );
+ MarkTransparent( Block.Glass, false ); MarkTransparent( Block.Leaves, false );
+ MarkTransparent( Block.Slab, true ); MarkTransparent( Block.Snow, true );
+ MarkTransparent( Block.CobblestoneSlab, true );
MarkSprite( Block.Rose ); MarkSprite( Block.Sapling );
MarkSprite( Block.Dandelion ); MarkSprite( Block.BrownMushroom );
MarkSprite( Block.RedMushroom ); MarkSprite( Block.Rope );
@@ -83,9 +83,9 @@ namespace ClassicalSharp {
canDelete[(int)Block.StillLava] = false;
}
- void MarkTransparent( Block id ) {
+ void MarkTransparent( Block id, bool blocks ) {
isTransparent[(int)id] = true;
- blocksLight[(int)id] = false;
+ blocksLight[(int)id] = blocks;
isOpaque[(int)id] = false;
}
diff --git a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs
index b68ba9c8d..1807676be 100644
--- a/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs
+++ b/ClassicalSharp/Map/ChunkMeshBuilderTex2Col4.cs
@@ -235,7 +235,7 @@ namespace ClassicalSharp {
int texId = info.GetTextureLoc( tile, TileSide.Bottom );
int i;
TextureRectangle rec = atlas.GetTexRec( texId, count, out i );
- FastColour col = Y > 0 ? ( emitsLight || (Y - 1) > map.heightmap[( Z * width ) + X] ? map.SunlightYBottom : map.ShadowlightYBottom )
+ FastColour col = Y > 0 ? ( emitsLight || Y > map.heightmap[( Z * width ) + X] ? map.SunlightYBottom : map.ShadowlightYBottom )
: map.SunlightYBottom;
DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
@@ -249,7 +249,7 @@ namespace ClassicalSharp {
int texId = info.GetTextureLoc( tile, TileSide.Top );
int i;
TextureRectangle rec = atlas.GetTexRec( texId, count, out i );
- FastColour col = Y < maxY ? ( emitsLight || (Y + 1) > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight )
+ FastColour col = Y < maxY ? ( emitsLight || Y > map.heightmap[( Z * width ) + X] ? map.Sunlight : map.Shadowlight )
: map.Sunlight;
DrawInfo part = isTranslucent ? drawInfoTranslucent[i] : drawInfoNormal[i];
diff --git a/ClassicalSharp/TexturePack/Animations.cs b/ClassicalSharp/TexturePack/Animations.cs
index 7dbafc5de..ee61e84c7 100644
--- a/ClassicalSharp/TexturePack/Animations.cs
+++ b/ClassicalSharp/TexturePack/Animations.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
+using System.IO;
using ClassicalSharp.GraphicsAPI;
namespace ClassicalSharp.TexturePack {
@@ -22,8 +23,6 @@ namespace ClassicalSharp.TexturePack {
Dispose();
this.bmp = bmp;
fastBmp = new FastBitmap( bmp, true );
- //DefineAnimation( 14, 0, 0, 0, 16, 32, 5 ); // water
- //DefineAnimation( 14, 1, 0, 16, 16, 20, 5 ); // lava
}
public void Dispose() {
@@ -41,12 +40,43 @@ namespace ClassicalSharp.TexturePack {
}
}
- public void DefineAnimation( int tileX, int tileY, int animX, int animY, int animSize,
+ public void ReadAnimationsDescription( StreamReader reader ) {
+ string line;
+ while( ( line = reader.ReadLine() ) != null ) {
+ if( line.Length == 0 || line[0] == '#' ) continue;
+
+ string[] parts = line.Split( ' ' );
+ if( parts.Length < 7 ) {
+ Utils.LogWarning( "Not enough arguments for animation: " + line ); continue;
+ }
+ byte tileX, tileY;
+ if( !Byte.TryParse( parts[0], out tileX ) || !Byte.TryParse( parts[1], out tileY )
+ || tileX >= 16 || tileY >= 16 ) {
+ Utils.LogWarning( "Invalid animation tile coordinates: " + line ); continue;
+ }
+
+ int frameX, frameY;
+ if( !Int32.TryParse( parts[2], out frameX ) || !Int32.TryParse( parts[3], out frameY )
+ || frameX < 0 || frameY < 0 ) {
+ Utils.LogWarning( "Invalid animation coordinates: " + line ); continue;
+ }
+
+ int frameSize, statesCount, tickDelay;
+ if( !Int32.TryParse( parts[4], out frameSize ) || !Int32.TryParse( parts[5], out statesCount ) ||
+ !Int32.TryParse( parts[6], out tickDelay ) || frameSize < 0 || statesCount < 0 || tickDelay < 0 ) {
+ Utils.LogWarning( "Invalid animation: " + line ); continue;
+ }
+
+ DefineAnimation( tileX, tileY, frameX, frameY, frameSize, statesCount, tickDelay );
+ }
+ }
+
+ public void DefineAnimation( int tileX, int tileY, int frameX, int frameY, int frameSize,
int statesNum, int tickDelay ) {
AnimationData data = new AnimationData();
data.TileX = tileX; data.TileY = tileY;
- data.AnimX = animX; data.AnimY = animY;
- data.AnimSize = animSize; data.StatesCount = statesNum;
+ data.FrameX = frameX; data.FrameY = frameY;
+ data.FrameSize = frameSize; data.StatesCount = statesNum;
data.TickDelay = tickDelay;
animations.Add( data );
}
@@ -54,7 +84,6 @@ namespace ClassicalSharp.TexturePack {
unsafe void ApplyAnimation( AnimationData data ) {
data.Tick--;
if( data.Tick >= 0 ) return;
- Console.WriteLine( "tick" );
data.CurrentState++;
data.CurrentState %= data.StatesCount;
data.Tick = data.TickDelay;
@@ -64,16 +93,16 @@ namespace ClassicalSharp.TexturePack {
int index = atlas.Get1DIndex( texId );
int rowNum = atlas.Get1DRowId( texId );
- int size = data.AnimSize;
+ int size = data.FrameSize;
byte* temp = stackalloc byte[size * size * 4];
FastBitmap part = new FastBitmap( size, size, size * 4, (IntPtr)temp );
- FastBitmap.MovePortion( data.AnimX + data.CurrentState * size, data.AnimY, 0, 0, fastBmp, part, size );
+ FastBitmap.MovePortion( data.FrameX + data.CurrentState * size, data.FrameY, 0, 0, fastBmp, part, size );
api.UpdateTexturePart( atlas.TexIds[index], 0, rowNum * game.TerrainAtlas.elementSize, part );
}
class AnimationData {
public int TileX, TileY;
- public int AnimX, AnimY, AnimSize;
+ public int FrameX, FrameY, FrameSize;
public int CurrentState;
public int StatesCount;
public int Tick, TickDelay;
diff --git a/ClassicalSharp/TexturePack/TexturePackExtractor.cs b/ClassicalSharp/TexturePack/TexturePackExtractor.cs
index acf0f05fe..707f9182a 100644
--- a/ClassicalSharp/TexturePack/TexturePackExtractor.cs
+++ b/ClassicalSharp/TexturePack/TexturePackExtractor.cs
@@ -56,9 +56,6 @@ namespace ClassicalSharp.TexturePack {
UpdateTexture( ref cache.SheepFurTexId, stream, false ); break;
case "char.png":
UpdateTexture( ref cache.HumanoidTexId, stream, true ); break;
- case "animations.png":
- case "animation.png":
- game.Animations.SetAtlas( new Bitmap( stream ) ); break;
case "clouds.png":
case "cloud.png":
UpdateTexture( ref game.CloudsTextureId, stream, false ); break;
@@ -66,6 +63,14 @@ namespace ClassicalSharp.TexturePack {
UpdateTexture( ref game.RainTextureId, stream, false ); break;
case "snow.png":
UpdateTexture( ref game.SnowTextureId, stream, false ); break;
+ case "animations.png":
+ case "animation.png":
+ game.Animations.SetAtlas( new Bitmap( stream ) ); break;
+ case "animations.txt":
+ case "animation.txt":
+ StreamReader reader = new StreamReader( stream );
+ game.Animations.ReadAnimationsDescription( reader );
+ break;
}
}
diff --git a/Launcher/Launcher.csproj b/Launcher/Launcher.csproj
index 395e9449c..a9cf5e4aa 100644
--- a/Launcher/Launcher.csproj
+++ b/Launcher/Launcher.csproj
@@ -85,6 +85,7 @@
+
diff --git a/Launcher/Patcher/Animations.cs b/Launcher/Patcher/Animations.cs
new file mode 100644
index 000000000..88fe92b00
--- /dev/null
+++ b/Launcher/Patcher/Animations.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Drawing;
+using System.IO;
+
+namespace Launcher {
+
+ public partial class ResourceFetcher {
+
+ const string animationsTxt = @"# This file defines the animations used in a texture pack for ClassicCube.
+# Each line is in the format:
+# - TileX and TileY indicate the coordinates of the tile in terrain.png that
+# will be replaced by the animation frames. These range from 0 to 15. (inclusive of 15)
+# - FrameX and FrameY indicates the pixel coordinates of the first animation frame in animations.png.
+# - Frame Size indicates the size in pixels of an animation frame.
+# - Frames count indicates the number of used frames. The first frame is located at
+# (FrameX, FrameY), the second one at (FrameX + FrameSize, FrameY) and so on.
+# - Tick delay is the number of ticks a frame doesn't change. For instance, a value of 0
+# means that the frame would be changed every tick, while a value of 2 would mean
+# 'replace with frame 1, don't change frame, don't change frame, replace with frame 2'.
+
+# still water
+14 0 0 0 16 32 2
+# still lava
+14 1 0 16 16 39 2
+# fire
+6 2 0 32 16 32 0";
+
+ unsafe void PatchDefault( byte[] data, int y ) {
+ // Sadly files in modern are 24 rgb, so we can't use fastbitmap here
+ using( Bitmap bmp = new Bitmap( new MemoryStream( data ) ) ) {
+ for( int tile = 0; tile < bmp.Height; tile += 16 ) {
+ CopyTile( tile, tile, y, bmp );
+ }
+ }
+ }
+
+ unsafe void PatchCycle( byte[] data, int y ) {
+ using( Bitmap bmp = new Bitmap( new MemoryStream( data ) ) ) {
+ int dst = 0;
+ for( int tile = 0; tile < bmp.Height; tile += 16, dst += 16 ) {
+ CopyTile( tile, dst, y, bmp );
+ }
+ // Cycle back to first frame.
+ for( int tile = bmp.Height - 32; tile >= 0; tile -= 16, dst += 16 ) {
+ CopyTile( tile, dst, y, bmp );
+ }
+ }
+ }
+ }
+}
diff --git a/Launcher/Patcher/ResourceFetcher.cs b/Launcher/Patcher/ResourceFetcher.cs
index 786c5dd24..fa696e389 100644
--- a/Launcher/Patcher/ResourceFetcher.cs
+++ b/Launcher/Patcher/ResourceFetcher.cs
@@ -9,7 +9,7 @@ using ClassicalSharp.TexturePack;
namespace Launcher {
- public class ResourceFetcher {
+ public partial class ResourceFetcher {
const string classicJarUri = "http://s3.amazonaws.com/Minecraft.Download/versions/c0.30_01c/c0.30_01c.jar";
const string modernJarUri = "http://s3.amazonaws.com/Minecraft.Download/versions/1.6.2/1.6.2.jar";
@@ -36,11 +36,12 @@ namespace Launcher {
reader.Extract( srcClassic );
// Grab animations and snow
- animBitmap = new Bitmap( 512, 32, PixelFormat.Format32bppArgb );
+ animBitmap = new Bitmap( 1024, 64, PixelFormat.Format32bppArgb );
reader.ShouldProcessZipEntry = ShouldProcessZipEntry_Modern;
reader.ProcessZipEntry = ProcessZipEntry_Modern;
reader.Extract( srcModern );
writer.WriteNewImage( animBitmap, "animations.png" );
+ writer.WriteNewString( animationsTxt, "animations.txt" );
animBitmap.Dispose();
writer.WriteCentralDirectoryRecords();
}
@@ -76,7 +77,8 @@ namespace Launcher {
( filename == "assets/minecraft/textures/environment/snow.png" ||
filename == "assets/minecraft/textures/blocks/water_still.png" ||
filename == "assets/minecraft/textures/blocks/lava_still.png" ||
- filename == "assets/minecraft/textures/entity/chicken.png" );
+ filename == "assets/minecraft/textures/blocks/fire_layer_1.png" ||
+ filename == "assets/minecraft/textures/entity/chicken.png" );
}
void ProcessZipEntry_Modern( string filename, byte[] data, ZipEntry entry ) {
@@ -90,10 +92,13 @@ namespace Launcher {
writer.WriteZipEntry( entry, data );
break;
case "assets/minecraft/textures/blocks/water_still.png":
- PatchAnimation( data, 0 );
+ PatchDefault( data, 0 );
break;
case "assets/minecraft/textures/blocks/lava_still.png":
- PatchAnimation( data, 16 );
+ PatchCycle( data, 16 );
+ break;
+ case "assets/minecraft/textures/blocks/fire_layer_1.png":
+ PatchDefault( data, 32 );
break;
}
}
@@ -114,16 +119,11 @@ namespace Launcher {
}
}
- unsafe void PatchAnimation( byte[] data, int y ) {
- // Sadly files in modern are 24 rgb, so we can't use fastbitmap here
- using( Bitmap bmp = new Bitmap( new MemoryStream( data ) ) ) {
- for( int tile = 0; tile < bmp.Height; tile += 16 ) {
- for( int yy = 0; yy < 16; yy++ ) {
- for( int xx = 0; xx < 16; xx++ ) {
- animBitmap.SetPixel( tile + xx, y + yy,
- bmp.GetPixel( xx, tile + yy ) );
- }
- }
+ void CopyTile( int src, int dst, int y, Bitmap bmp ) {
+ for( int yy = 0; yy < 16; yy++ ) {
+ for( int xx = 0; xx < 16; xx++ ) {
+ animBitmap.SetPixel( dst + xx, y + yy,
+ bmp.GetPixel( xx, src + yy ) );
}
}
}
diff --git a/Launcher/Patcher/ZipWriter.cs b/Launcher/Patcher/ZipWriter.cs
index c57febec3..3640fb532 100644
--- a/Launcher/Patcher/ZipWriter.cs
+++ b/Launcher/Patcher/ZipWriter.cs
@@ -2,6 +2,7 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
+using System.Text;
using ClassicalSharp.TexturePack;
namespace Launcher {
@@ -22,22 +23,31 @@ namespace Launcher {
entry.CompressedDataSize = (int)entry.UncompressedDataSize;
entry.LocalHeaderOffset = (int)stream.Position;
entries[entriesCount++] = entry;
- WriteLocalFileHeader( entry, data, data.Length );
+ WriteLocalFileEntry( entry, data, data.Length );
}
public void WriteNewImage( Bitmap bmp, string filename ) {
MemoryStream data = new MemoryStream();
bmp.Save( data, ImageFormat.Png );
byte[] buffer = data.GetBuffer();
-
+ WriteNewEntry( filename, buffer, (int)data.Length );
+ }
+
+ public void WriteNewString( string text, string filename ) {
+ byte[] data = Encoding.ASCII.GetBytes( text );
+ WriteNewEntry( filename, data, data.Length );
+ }
+
+ public void WriteNewEntry( string filename, byte[] data, int dataLength ) {
ZipEntry entry = new ZipEntry();
- entry.UncompressedDataSize = (int)data.Length;
- entry.Crc32 = CRC32( buffer, entry.UncompressedDataSize );
- entry.CompressedDataSize = entry.UncompressedDataSize;
+ entry.UncompressedDataSize = dataLength;
+ entry.Crc32 = CRC32( data, dataLength );
+ entry.CompressedDataSize = dataLength;
entry.LocalHeaderOffset = (int)stream.Position;
+
entry.Filename = filename;
entries[entriesCount++] = entry;
- WriteLocalFileHeader( entry, buffer, entry.UncompressedDataSize );
+ WriteLocalFileEntry( entry, data, dataLength );
}
public void WriteCentralDirectoryRecords() {
@@ -49,7 +59,7 @@ namespace Launcher {
WriteEndOfCentralDirectoryRecord( (ushort)entriesCount, dirSize, dirOffset );
}
- void WriteLocalFileHeader( ZipEntry entry, byte[] data, int length ) {
+ void WriteLocalFileEntry( ZipEntry entry, byte[] data, int length ) {
writer.Write( 0x04034b50 ); // signature
writer.Write( (ushort)20 ); // version needed
writer.Write( (ushort)8 ); // bitflags