mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-15 02:25:32 -04:00
Add SoundPatcher and refactor ResourceFetcher, in preparation for fetching sound/music resources.
This commit is contained in:
parent
b0dd9d0651
commit
b1a972a905
@ -71,6 +71,9 @@
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
||||
<ItemGroup>
|
||||
<Reference Include="SharpWave">
|
||||
<HintPath>SharpWave.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
@ -243,6 +246,9 @@
|
||||
<None Include="..\readme.md">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="SharpWave.dll.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="2D\Drawing" />
|
||||
|
66
ClassicalSharp/Particles/CollidableParticle.cs
Normal file
66
ClassicalSharp/Particles/CollidableParticle.cs
Normal file
@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using ClassicalSharp.Entities;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Particles {
|
||||
|
||||
public abstract class CollidableParticle : Particle {
|
||||
|
||||
const float gravity = 3.4f;
|
||||
//const float gravity = 0.7f; // TODO: temp debug
|
||||
|
||||
public CollidableParticle( Game game, Vector3 pos, Vector3 velocity, double lifetime )
|
||||
: base( game, pos, velocity, lifetime ) {
|
||||
}
|
||||
|
||||
public override bool Tick( double delta ) {
|
||||
lastPos = Position = nextPos;
|
||||
byte curBlock = game.World.SafeGetBlock( (int)Position.X, (int)Position.Y, (int)Position.Z );
|
||||
if( !CanPassThrough( curBlock ) ) return true;
|
||||
|
||||
Velocity.Y -= gravity * (float)delta;
|
||||
int startY = (int)Math.Floor( Position.Y );
|
||||
Position += Velocity * (float)delta * 3;
|
||||
int endY = (int)Math.Floor( Position.Y );
|
||||
Utils.Clamp( ref Position.X, 0, game.World.Width - 0.01f );
|
||||
Utils.Clamp( ref Position.Z, 0, game.World.Length - 0.01f );
|
||||
|
||||
if( Velocity.Y > 0 ) {
|
||||
for( int y = startY; y <= endY && TestY( y, false ); y++ );
|
||||
} else {
|
||||
for( int y = startY; y >= endY && TestY( y, true ); y-- );
|
||||
}
|
||||
nextPos = Position;
|
||||
Position = lastPos;
|
||||
return base.Tick( delta );
|
||||
}
|
||||
|
||||
bool TestY( int y, bool topFace ) {
|
||||
if( y < 0 ) {
|
||||
Position.Y = nextPos.Y = lastPos.Y = 0 + Entity.Adjustment;
|
||||
Velocity = Vector3.Zero;
|
||||
return false;
|
||||
}
|
||||
|
||||
byte block = game.World.SafeGetBlock( (int)Position.X, y, (int)Position.Z );
|
||||
if( CanPassThrough( block ) ) return true;
|
||||
|
||||
float collideY = y;
|
||||
if( topFace )
|
||||
collideY += game.BlockInfo.Height[block];
|
||||
|
||||
bool collide = topFace ? (Position.Y < collideY) : (Position.Y > collideY );
|
||||
if( collide ) {
|
||||
float adjust = topFace ? Entity.Adjustment : -Entity.Adjustment;
|
||||
Position.Y = nextPos.Y = lastPos.Y = collideY + adjust;
|
||||
Velocity = Vector3.Zero;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CanPassThrough( byte block ) {
|
||||
return block == 0 || game.BlockInfo.IsSprite[block] || game.BlockInfo.IsLiquid[block];
|
||||
}
|
||||
}
|
||||
}
|
28
ClassicalSharp/Particles/Particle.cs
Normal file
28
ClassicalSharp/Particles/Particle.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Particles {
|
||||
|
||||
public abstract class Particle {
|
||||
|
||||
public Vector3 Position;
|
||||
public Vector3 Velocity;
|
||||
public float Lifetime;
|
||||
protected Game game;
|
||||
protected Vector3 lastPos, nextPos;
|
||||
|
||||
public abstract void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index );
|
||||
|
||||
public Particle( Game game, Vector3 pos, Vector3 velocity, double lifetime ) {
|
||||
this.game = game;
|
||||
Position = lastPos = nextPos = pos;
|
||||
Velocity = velocity;
|
||||
Lifetime = (float)lifetime;
|
||||
}
|
||||
|
||||
public virtual bool Tick( double delta ) {
|
||||
Lifetime -= (float)delta;
|
||||
return Lifetime < 0;
|
||||
}
|
||||
}
|
||||
}
|
129
ClassicalSharp/Particles/ParticleManager.cs
Normal file
129
ClassicalSharp/Particles/ParticleManager.cs
Normal file
@ -0,0 +1,129 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ClassicalSharp.GraphicsAPI;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Particles {
|
||||
|
||||
public class ParticleManager : IDisposable {
|
||||
|
||||
public int ParticlesTexId;
|
||||
List<Particle> terrainParticles = new List<Particle>();
|
||||
List<Particle> rainParticles = new List<Particle>();
|
||||
Game game;
|
||||
Random rnd;
|
||||
int vb;
|
||||
|
||||
public ParticleManager( Game game ) {
|
||||
this.game = game;
|
||||
rnd = new Random();
|
||||
vb = game.Graphics.CreateDynamicVb( VertexFormat.Pos3fTex2fCol4b, 1000 );
|
||||
}
|
||||
|
||||
VertexPos3fTex2fCol4b[] vertices = new VertexPos3fTex2fCol4b[0];
|
||||
public void Render( double delta, float t ) {
|
||||
if( terrainParticles.Count == 0 && rainParticles.Count == 0 ) return;
|
||||
IGraphicsApi graphics = game.Graphics;
|
||||
graphics.Texturing = true;
|
||||
graphics.AlphaTest = true;
|
||||
graphics.SetBatchFormat( VertexFormat.Pos3fTex2fCol4b );
|
||||
|
||||
int count = RenderParticles( terrainParticles, delta, t );
|
||||
if( count > 0 ) {
|
||||
graphics.BindTexture( game.TerrainAtlas.TexId );
|
||||
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 );
|
||||
}
|
||||
count = RenderParticles( rainParticles, delta, t );
|
||||
if( count > 0 ) {
|
||||
graphics.BindTexture( ParticlesTexId );
|
||||
graphics.UpdateDynamicIndexedVb( DrawMode.Triangles, vb, vertices, count, count * 6 / 4 );
|
||||
}
|
||||
|
||||
graphics.AlphaTest = false;
|
||||
graphics.Texturing = false;
|
||||
}
|
||||
|
||||
int RenderParticles( List<Particle> particles, double delta, float t ) {
|
||||
int count = particles.Count * 4;
|
||||
if( count > vertices.Length )
|
||||
vertices = new VertexPos3fTex2fCol4b[count];
|
||||
|
||||
int index = 0;
|
||||
for( int i = 0; i < particles.Count; i++ )
|
||||
particles[i].Render( delta, t, vertices, ref index );
|
||||
return Math.Min( count, 1000 );
|
||||
}
|
||||
|
||||
public void Tick( double delta ) {
|
||||
TickParticles( terrainParticles, delta );
|
||||
TickParticles( rainParticles, delta );
|
||||
}
|
||||
|
||||
void TickParticles( List<Particle> particles, double delta ) {
|
||||
for( int i = 0; i < particles.Count; i++ ) {
|
||||
Particle particle = particles[i];
|
||||
if( particle.Tick( delta ) ) {
|
||||
particles.RemoveAt( i );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
game.Graphics.DeleteDynamicVb( vb );
|
||||
game.Graphics.DeleteTexture( ref ParticlesTexId );
|
||||
}
|
||||
|
||||
public void BreakBlockEffect( Vector3I position, byte block ) {
|
||||
Vector3 startPos = new Vector3( position.X, position.Y, position.Z );
|
||||
int texLoc = game.BlockInfo.GetTextureLoc( block, TileSide.Left );
|
||||
TextureRec rec = game.TerrainAtlas.GetTexRec( texLoc );
|
||||
|
||||
const float invSize = TerrainAtlas2D.invElementSize;
|
||||
const int cellsCount = (int)((1/4f) / invSize);
|
||||
const float elemSize = invSize / 4f;
|
||||
float blockHeight = game.BlockInfo.Height[block];
|
||||
|
||||
for( int i = 0; i < 25; i++ ) {
|
||||
double velX = rnd.NextDouble() * 0.8 - 0.4; // [-0.4, 0.4]
|
||||
double velZ = rnd.NextDouble() * 0.8 - 0.4;
|
||||
double velY = rnd.NextDouble() + 0.2;
|
||||
Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ );
|
||||
|
||||
double xOffset = rnd.NextDouble() - 0.5; // [-0.5, 0.5]
|
||||
double yOffset = (rnd.NextDouble() - 0.125) * blockHeight;
|
||||
double zOffset = rnd.NextDouble() - 0.5;
|
||||
Vector3 pos = startPos + new Vector3( 0.5f + (float)xOffset,
|
||||
(float)yOffset, 0.5f + (float)zOffset );
|
||||
|
||||
TextureRec particleRec = rec;
|
||||
particleRec.U1 = rec.U1 + rnd.Next( 0, cellsCount ) * elemSize;
|
||||
particleRec.V1 = rec.V1 + rnd.Next( 0, cellsCount ) * elemSize;
|
||||
particleRec.U2 = particleRec.U1 + elemSize;
|
||||
particleRec.V2 = particleRec.V1 + elemSize;
|
||||
double life = 1.5 - rnd.NextDouble();
|
||||
|
||||
terrainParticles.Add( new TerrainParticle( game, pos, velocity, life, particleRec ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRainParticle( Vector3 pos ) {
|
||||
Vector3 startPos = pos;
|
||||
|
||||
for( int i = 0; i < 5; i++ ) {
|
||||
double velX = rnd.NextDouble() * 0.8 - 0.4; // [-0.4, 0.4]
|
||||
double velZ = rnd.NextDouble() * 0.8 - 0.4;
|
||||
double velY = rnd.NextDouble() + 0.5;
|
||||
Vector3 velocity = new Vector3( (float)velX, (float)velY, (float)velZ );
|
||||
|
||||
double xOffset = rnd.NextDouble() - 0.5; // [-0.5, 0.5]
|
||||
double yOffset = 0.01;
|
||||
double zOffset = rnd.NextDouble() - 0.5;
|
||||
pos = startPos + new Vector3( 0.5f + (float)xOffset,
|
||||
(float)yOffset, 0.5f + (float)zOffset );
|
||||
double life = 3.5 - rnd.NextDouble();
|
||||
rainParticles.Add( new RainParticle( game, pos, velocity, life ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
ClassicalSharp/Particles/RainParticle.cs
Normal file
28
ClassicalSharp/Particles/RainParticle.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Particles {
|
||||
|
||||
public sealed class RainParticle : CollidableParticle {
|
||||
|
||||
static Vector2 rainSize = new Vector2( 1/8f, 1/8f );
|
||||
static TextureRec rec = new TextureRec( 2/128f, 14/128f, 3/128f, 2/128f );
|
||||
public RainParticle( Game game, Vector3 pos, Vector3 velocity, double lifetime )
|
||||
: base( game, pos, velocity, lifetime ) {
|
||||
}
|
||||
|
||||
public override void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index ) {
|
||||
Position = Vector3.Lerp( lastPos, nextPos, t );
|
||||
Vector3 p111, p121, p212, p222;
|
||||
Utils.CalcBillboardPoints( rainSize, Position, ref game.View,
|
||||
out p111, out p121, out p212, out p222 );
|
||||
World map = game.World;
|
||||
FastColour col = map.IsLit( Vector3I.Floor( Position ) ) ? map.Sunlight : map.Shadowlight;
|
||||
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p111, rec.U1, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p121, rec.U1, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col );
|
||||
}
|
||||
}
|
||||
}
|
29
ClassicalSharp/Particles/TerrainParticle.cs
Normal file
29
ClassicalSharp/Particles/TerrainParticle.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Particles {
|
||||
|
||||
public sealed class TerrainParticle : CollidableParticle {
|
||||
|
||||
static Vector2 terrainSize = new Vector2( 1/8f, 1/8f );
|
||||
TextureRec rec;
|
||||
public TerrainParticle( Game game, Vector3 pos, Vector3 velocity, double lifetime, TextureRec rec )
|
||||
: base( game, pos, velocity, lifetime ) {
|
||||
this.rec = rec;
|
||||
}
|
||||
|
||||
public override void Render( double delta, float t, VertexPos3fTex2fCol4b[] vertices, ref int index ) {
|
||||
Position = Vector3.Lerp( lastPos, nextPos, t );
|
||||
Vector3 p111, p121, p212, p222;
|
||||
Utils.CalcBillboardPoints( terrainSize, Position, ref game.View,
|
||||
out p111, out p121, out p212, out p222 );
|
||||
World map = game.World;
|
||||
FastColour col = map.IsLit( Vector3I.Floor( Position ) ) ? map.Sunlight : map.Shadowlight;
|
||||
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p111, rec.U1, rec.V2, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p121, rec.U1, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p222, rec.U2, rec.V1, col );
|
||||
vertices[index++] = new VertexPos3fTex2fCol4b( p212, rec.U2, rec.V2, col );
|
||||
}
|
||||
}
|
||||
}
|
BIN
ClassicalSharp/SharpWave.dll
Normal file
BIN
ClassicalSharp/SharpWave.dll
Normal file
Binary file not shown.
4
ClassicalSharp/SharpWave.dll.config
Normal file
4
ClassicalSharp/SharpWave.dll.config
Normal file
@ -0,0 +1,4 @@
|
||||
<configuration>
|
||||
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
|
||||
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
</configuration>
|
@ -48,10 +48,9 @@ namespace Launcher2 {
|
||||
game.Downloader = new AsyncDownloader( "null" );
|
||||
if( fetcher != null ) return;
|
||||
|
||||
fetcher = new ResourceFetcher( game.Downloader );
|
||||
fetcher.DownloadItems( SetStatus );
|
||||
fetcher = game.fetcher;
|
||||
fetcher.DownloadItems( game.Downloader, SetStatus );
|
||||
selectedWidget = null;
|
||||
|
||||
Resize();
|
||||
}
|
||||
|
||||
@ -59,7 +58,7 @@ namespace Launcher2 {
|
||||
static FastColour backCol = new FastColour( 120, 85, 151 );
|
||||
static readonly string mainText = "Some required resources weren't found" +
|
||||
Environment.NewLine + "Okay to download them?";
|
||||
static readonly string format = "Estimated size: {0} megabytes";
|
||||
static readonly string format = "Download size: {0} megabytes";
|
||||
static FastColour clearCol = new FastColour( 12, 12, 12 );
|
||||
|
||||
void Draw() {
|
||||
@ -68,8 +67,9 @@ namespace Launcher2 {
|
||||
drawer.DrawRect( backCol, game.Width / 2 - 175,
|
||||
game.Height / 2 - 70, 175 * 2, 70 * 2 );
|
||||
|
||||
float dataSize = game.fetcher.DownloadSize;
|
||||
string text = widgets[0] != null ? widgets[0].Text
|
||||
: String.Format( format, ResourceFetcher.EstimateDownloadSize() );
|
||||
: String.Format( format, dataSize.ToString( "F2" ) );
|
||||
MakeLabelAt( text, statusFont, Anchor.Centre, Anchor.Centre, 0, 5 );
|
||||
|
||||
// Clear the entire previous widgets state.
|
||||
|
@ -45,6 +45,9 @@
|
||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="SharpWave">
|
||||
<HintPath>..\ClassicalSharp\SharpWave.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Security" />
|
||||
@ -72,6 +75,7 @@
|
||||
<Compile Include="Patcher\Animations.cs" />
|
||||
<Compile Include="Patcher\ResourceFetcher.cs" />
|
||||
<Compile Include="Patcher\ResourcePatcher.cs" />
|
||||
<Compile Include="Patcher\SoundPatcher.cs" />
|
||||
<Compile Include="Patcher\ZipWriter.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
@ -48,6 +48,8 @@ namespace Launcher2 {
|
||||
public Dictionary<string, Dictionary<string, object>> ScreenMetadata =
|
||||
new Dictionary<string, Dictionary<string, object>>();
|
||||
|
||||
internal ResourceFetcher fetcher;
|
||||
|
||||
Font logoFont, logoItalicFont;
|
||||
PlatformDrawer platformDrawer;
|
||||
public void Init() {
|
||||
@ -120,7 +122,9 @@ namespace Launcher2 {
|
||||
TryLoadTexturePack();
|
||||
platformDrawer.Init( Window.WindowInfo );
|
||||
|
||||
if( !ResourceFetcher.CheckAllResourcesExist() ) {
|
||||
fetcher = new ResourceFetcher();
|
||||
fetcher.CheckResourceExistence();
|
||||
if( !fetcher.AllResourcesExist ) {
|
||||
SetScreen( new ResourcesScreen( this ) );
|
||||
} else {
|
||||
SetScreen( new MainScreen( this ) );
|
||||
|
@ -7,17 +7,22 @@ namespace Launcher2 {
|
||||
public sealed class ResourceFetcher {
|
||||
|
||||
public bool Done = false;
|
||||
AsyncDownloader downloader;
|
||||
public ResourceFetcher( AsyncDownloader downloader ) {
|
||||
this.downloader = downloader;
|
||||
internal AsyncDownloader downloader;
|
||||
public ResourceFetcher() {
|
||||
digPath = Path.Combine( "audio", "dig" );
|
||||
stepPath = Path.Combine( "audio", "step" );
|
||||
}
|
||||
|
||||
const string jarClassicUri = "http://s3.amazonaws.com/Minecraft.Download/versions/c0.30_01c/c0.30_01c.jar";
|
||||
const string jar162Uri = "http://s3.amazonaws.com/Minecraft.Download/versions/1.6.2/1.6.2.jar";
|
||||
const string pngTerrainPatchUri = "http://static.classicube.net/terrain-patch.png";
|
||||
const string pngGuiPatchUri = "http://static.classicube.net/gui.png";
|
||||
const string digSoundsUri = "http://s3.amazonaws.com/MinecraftResources/sound3/dig/";
|
||||
const string stepSoundsUri = "http://s3.amazonaws.com/MinecraftResources/sound3/step/";
|
||||
const string musicUri = "http://s3.amazonaws.com/MinecraftResources/music/";
|
||||
|
||||
public void DownloadItems( Action<string> setStatus ) {
|
||||
public void DownloadItems( AsyncDownloader downloader, Action<string> setStatus ) {
|
||||
this.downloader = downloader;
|
||||
downloader.DownloadData( jarClassicUri, false, "classic_jar" );
|
||||
downloader.DownloadData( jar162Uri, false, "162_jar" );
|
||||
downloader.DownloadData( pngTerrainPatchUri, false, "terrain_patch" );
|
||||
@ -69,14 +74,50 @@ namespace Launcher2 {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CheckAllResourcesExist() {
|
||||
return File.Exists( "default.zip" );
|
||||
}
|
||||
public void CheckResourceExistence() {
|
||||
AllResourcesExist = File.Exists( "default.zip" );
|
||||
//&& Directory.Exists( "audio" ) && File.Exists( digPath + ".bin" )
|
||||
//&& File.Exists( stepPath + ".bin" );
|
||||
|
||||
public static string EstimateDownloadSize() {
|
||||
float size = (291 + 4621 + 7 + 21) / 1024f;
|
||||
// classic.jar + 1.6.2.jar + terrain-patch.png + gui.png
|
||||
return size.ToString( "F2" );
|
||||
if( !File.Exists( "default.zip" ) ) {
|
||||
// classic.jar + 1.6.2.jar + terrain-patch.png + gui.png
|
||||
DownloadSize += (291 + 4621 + 7 + 21) / 1024f;
|
||||
ResourcesCount += 4;
|
||||
}
|
||||
|
||||
for( int i = 0; i < musicFiles.Length; i++ ) {
|
||||
string file = Path.Combine( "audio", musicFiles[i] + ".ogg" );
|
||||
musicExists[i] = File.Exists( file );
|
||||
continue;
|
||||
// TODO: download music files
|
||||
if( !musicExists[i] ) {
|
||||
DownloadSize += musicSizes[i] / 1024f;
|
||||
ResourcesCount++;
|
||||
}
|
||||
}
|
||||
ResourcesCount += digSounds.Length;
|
||||
ResourcesCount += stepSounds.Length;
|
||||
}
|
||||
public bool AllResourcesExist;
|
||||
public float DownloadSize;
|
||||
public int ResourcesCount;
|
||||
|
||||
string digPath, stepPath;
|
||||
string[] digSounds = new [] { "cloth1", "cloth2", "cloth3", "cloth4",
|
||||
"glass1", "glass2", "glass3", "glass4", "grass1", "grass2", "grass3",
|
||||
"grass4", "gravel1", "gravel2", "gravel3", "gravel4", "sand1", "sand2",
|
||||
"sand3", "sand4", "snow1", "snow2", "snow3", "snow4", "stone1", "stone2",
|
||||
"stone3", "stone4", "wood1", "wood2", "wood3", "wood4" };
|
||||
|
||||
string[] stepSounds = new [] { "cloth1", "cloth2", "cloth3", "cloth4", "grass1",
|
||||
"grass2", "grass3", "grass4", "grass5", "grass6", "gravel1", "gravel2",
|
||||
"gravel3", "gravel4", "sand1", "sand2", "sand3", "sand4", "sand5", "snow1",
|
||||
"snow2", "snow3", "snow4", "stone1", "stone2", "stone3", "stone4", "stone5",
|
||||
"stone6", "wood1", "wood2", "wood3", "wood4", "wood5", "wood6" };
|
||||
|
||||
string[] musicFiles = new [] { "calm1", "calm2",
|
||||
"calm3", "hal1", "hal2", "hal3" };
|
||||
int[] musicSizes = new [] { 2472, 1931, 2181, 1926, 1714, 1879, 2499 };
|
||||
bool[] musicExists = new bool[6];
|
||||
}
|
||||
}
|
||||
|
88
Launcher2/Patcher/SoundPatcher.cs
Normal file
88
Launcher2/Patcher/SoundPatcher.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using ClassicalSharp.Network;
|
||||
using SharpWave;
|
||||
using SharpWave.Codecs;
|
||||
using SharpWave.Codecs.Vorbis;
|
||||
using SharpWave.Containers;
|
||||
|
||||
namespace Launcher2 {
|
||||
|
||||
public sealed class SoundPatcher {
|
||||
|
||||
string[] files, identifiers;
|
||||
string prefix;
|
||||
FileStream outData;
|
||||
StreamWriter outText;
|
||||
RawOut outDecoder;
|
||||
|
||||
public SoundPatcher( string[] files, string prefix, string outputPath ) {
|
||||
this.files = files;
|
||||
this.prefix = prefix;
|
||||
InitOutput( outputPath );
|
||||
}
|
||||
|
||||
public void FetchFiles( string baseUrl, ResourceFetcher fetcher ) {
|
||||
identifiers = new string[files.Length];
|
||||
for( int i = 0; i < files.Length; i++ )
|
||||
identifiers[i] = prefix + files[i];
|
||||
|
||||
for( int i = 0; i < files.Length; i++ ) {
|
||||
string url = baseUrl + files[i] + ".ogg";
|
||||
fetcher.downloader.DownloadData( url, false, identifiers[i] );
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckDownloaded( ResourceFetcher fetcher, Action<string> setStatus ) {
|
||||
for( int i = 0; i < identifiers.Length; i++ ) {
|
||||
DownloadedItem item;
|
||||
if( fetcher.downloader.TryGetItem( identifiers[i], out item ) ) {
|
||||
Console.WriteLine( "found sound " + identifiers[i] );
|
||||
if( item.Data == null ) {
|
||||
setStatus( "&cFailed to download " + identifiers[i] );
|
||||
return false;
|
||||
}
|
||||
DecodeSound( files[i], (byte[])item.Data );
|
||||
|
||||
// TODO: setStatus( next );
|
||||
if( i == identifiers.Length - 1 ) {
|
||||
Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DecodeSound( string name, byte[] rawData ) {
|
||||
long start = outData.Position;
|
||||
using( MemoryStream ms = new MemoryStream( rawData ) ) {
|
||||
OggContainer container = new OggContainer( ms );
|
||||
outDecoder.PlayStreaming( container );
|
||||
}
|
||||
|
||||
long len = outData.Position - start;
|
||||
outText.WriteLine( format, name, outDecoder.Frequency,
|
||||
outDecoder.BitsPerSample, outDecoder.Channels,
|
||||
start, len );
|
||||
}
|
||||
|
||||
const string format = "{0},{1},{2},{3},{4},{5}";
|
||||
void InitOutput( string outputPath ) {
|
||||
outData = File.Create( outputPath + ".bin" );
|
||||
outText = new StreamWriter( outputPath + ".txt" );
|
||||
outDecoder = new RawOut( outData, true );
|
||||
|
||||
outText.WriteLine( "# This file indicates where the various raw decompressed sound data " +
|
||||
"are found in the corresponding raw .bin file." );
|
||||
outText.WriteLine( "# Each line is in the following format:" );
|
||||
outText.WriteLine( "# Identifier, Frequency/Sample rate, BitsPerSample, " +
|
||||
"Channels, Offset from start, Length in bytes" );
|
||||
}
|
||||
|
||||
void Dispose() {
|
||||
outDecoder.Dispose();
|
||||
outData.Close();
|
||||
outText.Close();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user