Normalize the repo

This commit is contained in:
Christian 2012-08-01 21:05:35 -02:30
parent 3a0a329c77
commit c21dca182c
64 changed files with 66092 additions and 66091 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
/* /*
!/forge !/forge

8
forge/.gitignore vendored
View File

@ -1,4 +1,4 @@
/fml/ /fml/
/logs/ /logs/
/*.pyc /*.pyc
/forge-*/ /forge-*/

View File

@ -1 +1 @@
asdfsnb -a -v "svn"+ asdfsnb -a -v "svn"+

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
// this is needed for the sound engine to work with deobfuscated sourcecode without crashing // this is needed for the sound engine to work with deobfuscated sourcecode without crashing
public class gk public class gk
{ {
public static int c(double d) public static int c(double d)
{ {
int i = (int)d; int i = (int)d;
return d >= (double)i ? i : i - 1; return d >= (double)i ? i : i - 1;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +1,117 @@
diff -r -U 3 minecraft\net\minecraft\client\Minecraft.java minecraft_patched\net\minecraft\client\Minecraft.java diff -r -U 3 minecraft\net\minecraft\client\Minecraft.java minecraft_patched\net\minecraft\client\Minecraft.java
--- minecraft\net\minecraft\client\Minecraft.java Fri Mar 30 23:25:51 2012 --- minecraft\net\minecraft\client\Minecraft.java Fri Mar 30 23:25:51 2012
+++ minecraft_patched\net\minecraft\client\Minecraft.java Fri Mar 30 23:38:36 2012 +++ minecraft_patched\net\minecraft\client\Minecraft.java Fri Mar 30 23:38:36 2012
@@ -1618,11 +1618,13 @@ @@ -1618,11 +1618,13 @@
this.field_6324_e.func_600_a(var6.field_22395_a + var10, 64, var6.field_22396_c + var8); this.field_6324_e.func_600_a(var6.field_22395_a + var10, 64, var6.field_22396_c + var8);
if(!this.field_6327_b.func_35643_e()) { if(!this.field_6327_b.func_35643_e()) {
+/* +/*
while(true) { while(true) {
if(this.field_6324_e.func_6465_g()) { if(this.field_6324_e.func_6465_g()) {
continue; continue;
} }
} }
+*/ +*/
} }
} }
} }
diff -r -U 3 minecraft\net\minecraft\src\CodecMus.java minecraft_patched\net\minecraft\src\CodecMus.java diff -r -U 3 minecraft\net\minecraft\src\CodecMus.java minecraft_patched\net\minecraft\src\CodecMus.java
--- minecraft\net\minecraft\src\CodecMus.java Fri Mar 30 23:25:52 2012 --- minecraft\net\minecraft\src\CodecMus.java Fri Mar 30 23:25:52 2012
+++ minecraft_patched\net\minecraft\src\CodecMus.java Fri Mar 30 23:38:36 2012 +++ minecraft_patched\net\minecraft\src\CodecMus.java Fri Mar 30 23:38:36 2012
@@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
package net.minecraft.src; package net.minecraft.src;
+import java.io.IOException; +import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import net.minecraft.src.MusInputStream; import net.minecraft.src.MusInputStream;
import paulscode.sound.codecs.CodecJOrbis; import paulscode.sound.codecs.CodecJOrbis;
@@ -7,6 +8,11 @@ @@ -7,6 +8,11 @@
public class CodecMus extends CodecJOrbis { public class CodecMus extends CodecJOrbis {
protected InputStream openInputStream() { protected InputStream openInputStream() {
+ try { + try {
return new MusInputStream(this, this.url, this.urlConnection.getInputStream()); return new MusInputStream(this, this.url, this.urlConnection.getInputStream());
+ } + }
+ catch (IOException e) { + catch (IOException e) {
+ return null; + return null;
+ } + }
} }
} }
diff -r -U 3 minecraft\net\minecraft\src\ItemMap.java minecraft_patched\net\minecraft\src\ItemMap.java diff -r -U 3 minecraft\net\minecraft\src\ItemMap.java minecraft_patched\net\minecraft\src\ItemMap.java
--- minecraft\net\minecraft\src\ItemMap.java Fri Mar 30 23:25:53 2012 --- minecraft\net\minecraft\src\ItemMap.java Fri Mar 30 23:25:53 2012
+++ minecraft_patched\net\minecraft\src\ItemMap.java Fri Mar 30 23:38:36 2012 +++ minecraft_patched\net\minecraft\src\ItemMap.java Fri Mar 30 23:38:36 2012
@@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
} }
public static MapData func_28013_a(short p_28013_0_, World p_28013_1_) { public static MapData func_28013_a(short p_28013_0_, World p_28013_1_) {
- "map_" + p_28013_0_; - "map_" + p_28013_0_;
MapData var3 = (MapData)p_28013_1_.func_28103_a(MapData.class, "map_" + p_28013_0_); MapData var3 = (MapData)p_28013_1_.func_28103_a(MapData.class, "map_" + p_28013_0_);
if(var3 == null) { if(var3 == null) {
int var4 = p_28013_1_.func_28101_b("map"); int var4 = p_28013_1_.func_28101_b("map");
@@ -32,7 +31,6 @@ @@ -32,7 +31,6 @@
} }
public MapData func_28012_a(ItemStack p_28012_1_, World p_28012_2_) { public MapData func_28012_a(ItemStack p_28012_1_, World p_28012_2_) {
- "map_" + p_28012_1_.func_21181_i(); - "map_" + p_28012_1_.func_21181_i();
MapData var4 = (MapData)p_28012_2_.func_28103_a(MapData.class, "map_" + p_28012_1_.func_21181_i()); MapData var4 = (MapData)p_28012_2_.func_28103_a(MapData.class, "map_" + p_28012_1_.func_21181_i());
if(var4 == null) { if(var4 == null) {
p_28012_1_.func_28156_b(p_28012_2_.func_28101_b("map")); p_28012_1_.func_28156_b(p_28012_2_.func_28101_b("map"));
diff -r -U 3 minecraft\net\minecraft\src\MusInputStream.java minecraft_patched\net\minecraft\src\MusInputStream.java diff -r -U 3 minecraft\net\minecraft\src\MusInputStream.java minecraft_patched\net\minecraft\src\MusInputStream.java
--- minecraft\net\minecraft\src\MusInputStream.java Fri Mar 30 23:25:54 2012 --- minecraft\net\minecraft\src\MusInputStream.java Fri Mar 30 23:25:54 2012
+++ minecraft_patched\net\minecraft\src\MusInputStream.java Fri Mar 30 23:38:36 2012 +++ minecraft_patched\net\minecraft\src\MusInputStream.java Fri Mar 30 23:38:36 2012
@@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
package net.minecraft.src; package net.minecraft.src;
+import java.io.IOException; +import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import net.minecraft.src.CodecMus; import net.minecraft.src.CodecMus;
@@ -27,7 +28,12 @@ @@ -27,7 +28,12 @@
} }
public int read(byte[] p_read_1_, int p_read_2_, int p_read_3_) { public int read(byte[] p_read_1_, int p_read_2_, int p_read_3_) {
+ try { + try {
p_read_3_ = this.field_1515_d.read(p_read_1_, p_read_2_, p_read_3_); p_read_3_ = this.field_1515_d.read(p_read_1_, p_read_2_, p_read_3_);
+ } + }
+ catch (IOException e) { + catch (IOException e) {
+ return 0; + return 0;
+ } + }
for(int var4 = 0; var4 < p_read_3_; ++var4) { for(int var4 = 0; var4 < p_read_3_; ++var4) {
byte var5 = p_read_1_[p_read_2_ + var4] = (byte)(p_read_1_[p_read_2_ + var4] ^ this.field_1516_c >> 8); byte var5 = p_read_1_[p_read_2_ + var4] = (byte)(p_read_1_[p_read_2_ + var4] ^ this.field_1516_c >> 8);
diff -r -U 3 minecraft\net\minecraft\src\NetworkMasterThread.java minecraft_patched\net\minecraft\src\NetworkMasterThread.java diff -r -U 3 minecraft\net\minecraft\src\NetworkMasterThread.java minecraft_patched\net\minecraft\src\NetworkMasterThread.java
--- minecraft\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:25:54 2012 --- minecraft\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:25:54 2012
+++ minecraft_patched\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:38:36 2012 +++ minecraft_patched\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:38:36 2012
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
this.field_1086_a = p_i570_1_; this.field_1086_a = p_i570_1_;
} }
+ @SuppressWarnings("deprecation") + @SuppressWarnings("deprecation")
public void run() { public void run() {
try { try {
Thread.sleep(5000L); Thread.sleep(5000L);
diff -r -U 3 minecraft\net\minecraft\src\RenderGlobal.java minecraft_patched\net\minecraft\src\RenderGlobal.java diff -r -U 3 minecraft\net\minecraft\src\RenderGlobal.java minecraft_patched\net\minecraft\src\RenderGlobal.java
--- minecraft\net\minecraft\src\RenderGlobal.java Fri Mar 30 23:25:54 2012 --- minecraft\net\minecraft\src\RenderGlobal.java Fri Mar 30 23:25:54 2012
+++ minecraft_patched\net\minecraft\src\RenderGlobal.java Fri Mar 30 23:38:36 2012 +++ minecraft_patched\net\minecraft\src\RenderGlobal.java Fri Mar 30 23:38:36 2012
@@ -1458,7 +1458,7 @@ @@ -1458,7 +1458,7 @@
double var15 = this.field_1439_t.field_22009_h.field_611_ak - p_40193_2_; double var15 = this.field_1439_t.field_22009_h.field_611_ak - p_40193_2_;
double var17 = this.field_1439_t.field_22009_h.field_610_al - p_40193_4_; double var17 = this.field_1439_t.field_22009_h.field_610_al - p_40193_4_;
double var19 = this.field_1439_t.field_22009_h.field_609_am - p_40193_6_; double var19 = this.field_1439_t.field_22009_h.field_609_am - p_40193_6_;
- Object var21 = null; - Object var21 = null;
+ EntityFX var21 = null; + EntityFX var21 = null;
if(p_40193_1_.equals("hugeexplosion")) { if(p_40193_1_.equals("hugeexplosion")) {
this.field_1439_t.field_6321_h.func_1192_a(var21 = new EntityHugeExplodeFX(this.field_1448_k, p_40193_2_, p_40193_4_, p_40193_6_, p_40193_8_, p_40193_10_, p_40193_12_)); this.field_1439_t.field_6321_h.func_1192_a(var21 = new EntityHugeExplodeFX(this.field_1448_k, p_40193_2_, p_40193_4_, p_40193_6_, p_40193_8_, p_40193_10_, p_40193_12_));
} else if(p_40193_1_.equals("largeexplode")) { } else if(p_40193_1_.equals("largeexplode")) {
diff -r -U 3 minecraft\net\minecraft\src\ThreadedFileIOBase.java minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java diff -r -U 3 minecraft\net\minecraft\src\ThreadedFileIOBase.java minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java
--- minecraft\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:25:55 2012 --- minecraft\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:25:55 2012
+++ minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:38:36 2012 +++ minecraft_patched\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:38:36 2012
@@ -20,7 +20,9 @@ @@ -20,7 +20,9 @@
} }
public void run() { public void run() {
+ while (true) { + while (true) {
this.func_40568_b(); this.func_40568_b();
+ } + }
} }
private void func_40568_b() { private void func_40568_b() {

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,35 @@
diff -r -U 3 minecraft_server\net\minecraft\src\ItemMap.java minecraft_server_patched\net\minecraft\src\ItemMap.java diff -r -U 3 minecraft_server\net\minecraft\src\ItemMap.java minecraft_server_patched\net\minecraft\src\ItemMap.java
--- minecraft_server\net\minecraft\src\ItemMap.java Fri Mar 30 23:27:06 2012 --- minecraft_server\net\minecraft\src\ItemMap.java Fri Mar 30 23:27:06 2012
+++ minecraft_server_patched\net\minecraft\src\ItemMap.java Fri Mar 30 23:40:00 2012 +++ minecraft_server_patched\net\minecraft\src\ItemMap.java Fri Mar 30 23:40:00 2012
@@ -22,7 +22,6 @@ @@ -22,7 +22,6 @@
} }
public MapData func_28023_a(ItemStack p_28023_1_, World p_28023_2_) { public MapData func_28023_a(ItemStack p_28023_1_, World p_28023_2_) {
- "map_" + p_28023_1_.func_21125_h(); - "map_" + p_28023_1_.func_21125_h();
MapData var4 = (MapData)p_28023_2_.func_28103_a(MapData.class, "map_" + p_28023_1_.func_21125_h()); MapData var4 = (MapData)p_28023_2_.func_28103_a(MapData.class, "map_" + p_28023_1_.func_21125_h());
if(var4 == null) { if(var4 == null) {
p_28023_1_.func_28145_b(p_28023_2_.func_28104_b("map")); p_28023_1_.func_28145_b(p_28023_2_.func_28104_b("map"));
diff -r -U 3 minecraft_server\net\minecraft\src\NetworkMasterThread.java minecraft_server_patched\net\minecraft\src\NetworkMasterThread.java diff -r -U 3 minecraft_server\net\minecraft\src\NetworkMasterThread.java minecraft_server_patched\net\minecraft\src\NetworkMasterThread.java
--- minecraft_server\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:27:07 2012 --- minecraft_server\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:27:07 2012
+++ minecraft_server_patched\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:40:00 2012 +++ minecraft_server_patched\net\minecraft\src\NetworkMasterThread.java Fri Mar 30 23:40:00 2012
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
this.field_829_a = p_i577_1_; this.field_829_a = p_i577_1_;
} }
+ @SuppressWarnings("deprecation") + @SuppressWarnings("deprecation")
public void run() { public void run() {
try { try {
Thread.sleep(5000L); Thread.sleep(5000L);
diff -r -U 3 minecraft_server\net\minecraft\src\ThreadedFileIOBase.java minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java diff -r -U 3 minecraft_server\net\minecraft\src\ThreadedFileIOBase.java minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java
--- minecraft_server\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:27:07 2012 --- minecraft_server\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:27:07 2012
+++ minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:40:00 2012 +++ minecraft_server_patched\net\minecraft\src\ThreadedFileIOBase.java Fri Mar 30 23:40:00 2012
@@ -20,7 +20,9 @@ @@ -20,7 +20,9 @@
} }
public void run() { public void run() {
+ while (true) { + while (true) {
this.func_40509_b(); this.func_40509_b();
+ } + }
} }
private void func_40509_b() { private void func_40509_b() {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
[VERSION] [VERSION]
MCPVersion = 6.2 MCPVersion = 6.2
ClientVersion = 1.2.5 ClientVersion = 1.2.5
ServerVersion = 1.2.5 ServerVersion = 1.2.5

View File

@ -1,24 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="forge_common"/> <classpathentry kind="src" path="forge_common"/>
<classpathentry kind="src" path="minecraft"/> <classpathentry kind="src" path="minecraft"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="../../jars/bin/jinput.jar"> <classpathentry kind="lib" path="../../jars/bin/jinput.jar">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="forge_client/jars/bin/natives"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="forge_client/jars/bin/natives"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="../../jars/bin/lwjgl.jar"> <classpathentry kind="lib" path="../../jars/bin/lwjgl.jar">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="forge_client/jars/bin/natives"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="forge_client/jars/bin/natives"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="../../jars/bin/lwjgl_util.jar"> <classpathentry kind="lib" path="../../jars/bin/lwjgl_util.jar">
<attributes> <attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="forge_client/jars/bin/natives"/> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="forge_client/jars/bin/natives"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="../../jars/bin/minecraft.jar"/> <classpathentry kind="lib" path="../../jars/bin/minecraft.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@ -1 +1 @@
/bin/ /bin/

View File

@ -1,69 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>forge_client</name> <name>forge_client</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>
<buildSpec> <buildSpec>
<buildCommand> <buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name> <name>org.eclipse.jdt.core.javabuilder</name>
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
</buildSpec> </buildSpec>
<natures> <natures>
<nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jdt.core.javanature</nature>
</natures> </natures>
<linkedResources> <linkedResources>
<link> <link>
<name>forge_common</name> <name>forge_common</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/forge_common</locationURI> <locationURI>PARENT-1-PROJECT_LOC/forge_common</locationURI>
</link> </link>
<link> <link>
<name>jars</name> <name>jars</name>
<type>2</type> <type>2</type>
<locationURI>MCP_LOC/jars</locationURI> <locationURI>MCP_LOC/jars</locationURI>
</link> </link>
<link> <link>
<name>minecraft</name> <name>minecraft</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-1-WORKSPACE_LOC/src_work/minecraft</locationURI> <locationURI>PARENT-1-WORKSPACE_LOC/src_work/minecraft</locationURI>
</link> </link>
</linkedResources> </linkedResources>
<filteredResources> <filteredResources>
<filter> <filter>
<id>1324024223159</id> <id>1324024223159</id>
<name>jars</name> <name>jars</name>
<type>9</type> <type>9</type>
<matcher> <matcher>
<id>org.eclipse.ui.ide.multiFilter</id> <id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-bin</arguments> <arguments>1.0-name-matches-false-false-bin</arguments>
</matcher> </matcher>
</filter> </filter>
<filter> <filter>
<id>1324024223163</id> <id>1324024223163</id>
<name>jars</name> <name>jars</name>
<type>6</type> <type>6</type>
<matcher> <matcher>
<id>org.eclipse.ui.ide.multiFilter</id> <id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*</arguments> <arguments>1.0-name-matches-false-false-*</arguments>
</matcher> </matcher>
</filter> </filter>
<filter> <filter>
<id>1324024144075</id> <id>1324024144075</id>
<name>jars/bin</name> <name>jars/bin</name>
<type>5</type> <type>5</type>
<matcher> <matcher>
<id>org.eclipse.ui.ide.multiFilter</id> <id>org.eclipse.ui.ide.multiFilter</id>
<arguments>1.0-name-matches-false-false-*.jar</arguments> <arguments>1.0-name-matches-false-false-*.jar</arguments>
</matcher> </matcher>
</filter> </filter>
</filteredResources> </filteredResources>
<variableList> <variableList>
<variable> <variable>
<name>MCP_LOC</name> <name>MCP_LOC</name>
<value>$%7BPARENT-1-WORKSPACE_LOC%7D</value> <value>$%7BPARENT-1-WORKSPACE_LOC%7D</value>
</variable> </variable>
</variableList> </variableList>
</projectDescription> </projectDescription>

File diff suppressed because it is too large Load Diff

View File

@ -1,111 +1,111 @@
package ibxm; package ibxm;
public class Envelope { public class Envelope {
public boolean sustain, looped; public boolean sustain, looped;
private int sustain_tick, loop_start_tick, loop_end_tick; private int sustain_tick, loop_start_tick, loop_end_tick;
private int[] ticks, ampls; private int[] ticks, ampls;
public Envelope() { public Envelope() {
set_num_points( 1 ); set_num_points( 1 );
} }
public void set_num_points( int num_points ) { public void set_num_points( int num_points ) {
int point; int point;
if( num_points <= 0 ) { if( num_points <= 0 ) {
num_points = 1; num_points = 1;
} }
ticks = new int[ num_points ]; ticks = new int[ num_points ];
ampls = new int[ num_points ]; ampls = new int[ num_points ];
set_point( 0, 0, 0, false ); set_point( 0, 0, 0, false );
} }
/* When you set a point, all subsequent points are reset. */ /* When you set a point, all subsequent points are reset. */
public void set_point( int point, int tick, int ampl, boolean delta ) { public void set_point( int point, int tick, int ampl, boolean delta ) {
if( point >= 0 && point < ticks.length ) { if( point >= 0 && point < ticks.length ) {
if( point == 0 ) { if( point == 0 ) {
tick = 0; tick = 0;
} }
if( point > 0 ) { if( point > 0 ) {
if( delta ) tick += ticks[ point - 1 ]; if( delta ) tick += ticks[ point - 1 ];
if( tick <= ticks[ point - 1 ] ) { if( tick <= ticks[ point - 1 ] ) {
System.out.println( "Envelope: Point not valid (" + tick + " <= " + ticks[ point - 1 ] + ")"); System.out.println( "Envelope: Point not valid (" + tick + " <= " + ticks[ point - 1 ] + ")");
tick = ticks[ point - 1 ] + 1; tick = ticks[ point - 1 ] + 1;
} }
} }
ticks[ point ] = tick; ticks[ point ] = tick;
ampls[ point ] = ampl; ampls[ point ] = ampl;
point += 1; point += 1;
while( point < ticks.length ) { while( point < ticks.length ) {
ticks[ point ] = ticks[ point - 1 ] + 1; ticks[ point ] = ticks[ point - 1 ] + 1;
ampls[ point ] = 0; ampls[ point ] = 0;
point += 1; point += 1;
} }
} }
} }
public void set_sustain_point( int point ) { public void set_sustain_point( int point ) {
if( point < 0 ) { if( point < 0 ) {
point = 0; point = 0;
} }
if( point >= ticks.length ) { if( point >= ticks.length ) {
point = ticks.length - 1; point = ticks.length - 1;
} }
sustain_tick = ticks[ point ]; sustain_tick = ticks[ point ];
} }
public void set_loop_points( int start, int end ) { public void set_loop_points( int start, int end ) {
if( start < 0 ) { if( start < 0 ) {
start = 0; start = 0;
} }
if( start >= ticks.length ) { if( start >= ticks.length ) {
start = ticks.length - 1; start = ticks.length - 1;
} }
if( end < start || end >= ticks.length ) { if( end < start || end >= ticks.length ) {
end = start; end = start;
} }
loop_start_tick = ticks[ start ]; loop_start_tick = ticks[ start ];
loop_end_tick = ticks[ end ]; loop_end_tick = ticks[ end ];
} }
public int next_tick( int tick, boolean key_on ) { public int next_tick( int tick, boolean key_on ) {
tick = tick + 1; tick = tick + 1;
if( looped && tick >= loop_end_tick ) { if( looped && tick >= loop_end_tick ) {
tick = loop_start_tick; tick = loop_start_tick;
} }
if( sustain && key_on && tick >= sustain_tick ) { if( sustain && key_on && tick >= sustain_tick ) {
tick = sustain_tick; tick = sustain_tick;
} }
return tick; return tick;
} }
public int calculate_ampl( int tick ) { public int calculate_ampl( int tick ) {
int idx, point, delta_t, delta_a, ampl; int idx, point, delta_t, delta_a, ampl;
ampl = ampls[ ticks.length - 1 ]; ampl = ampls[ ticks.length - 1 ];
if( tick < ticks[ ticks.length - 1 ] ) { if( tick < ticks[ ticks.length - 1 ] ) {
point = 0; point = 0;
for( idx = 1; idx < ticks.length; idx++ ) { for( idx = 1; idx < ticks.length; idx++ ) {
if( ticks[ idx ] <= tick ) { if( ticks[ idx ] <= tick ) {
point = idx; point = idx;
} }
} }
delta_t = ticks[ point + 1 ] - ticks[ point ]; delta_t = ticks[ point + 1 ] - ticks[ point ];
delta_a = ampls[ point + 1 ] - ampls[ point ]; delta_a = ampls[ point + 1 ] - ampls[ point ];
ampl = ( delta_a << IBXM.FP_SHIFT ) / delta_t; ampl = ( delta_a << IBXM.FP_SHIFT ) / delta_t;
ampl = ampl * ( tick - ticks[ point ] ) >> IBXM.FP_SHIFT; ampl = ampl * ( tick - ticks[ point ] ) >> IBXM.FP_SHIFT;
ampl = ampl + ampls[ point ]; ampl = ampl + ampls[ point ];
} }
return ampl; return ampl;
} }
public void dump() { public void dump() {
int idx, tick; int idx, tick;
for( idx = 0; idx < ticks.length; idx++ ) { for( idx = 0; idx < ticks.length; idx++ ) {
System.out.println( ticks[ idx ] + ", " + ampls[ idx ] ); System.out.println( ticks[ idx ] + ", " + ampls[ idx ] );
} }
for( tick = 0; tick < 222; tick++ ) { for( tick = 0; tick < 222; tick++ ) {
System.out.print( calculate_ampl( tick ) + ", " ); System.out.print( calculate_ampl( tick ) + ", " );
} }
} }
} }

View File

@ -1,256 +1,256 @@
package ibxm; package ibxm;
import java.io.*; import java.io.*;
public class FastTracker2 { public class FastTracker2 {
public static boolean is_xm( byte[] header_60_bytes ) { public static boolean is_xm( byte[] header_60_bytes ) {
String xm_identifier; String xm_identifier;
xm_identifier = ascii_text( header_60_bytes, 0, 17 ); xm_identifier = ascii_text( header_60_bytes, 0, 17 );
return xm_identifier.equals( "Extended Module: " ); return xm_identifier.equals( "Extended Module: " );
} }
public static Module load_xm( byte[] header_60_bytes, DataInput data_input ) throws IOException { public static Module load_xm( byte[] header_60_bytes, DataInput data_input ) throws IOException {
int xm_version, song_header_length, sequence_length; int xm_version, song_header_length, sequence_length;
int num_channels, num_patterns, num_instruments, xm_flags, idx; int num_channels, num_patterns, num_instruments, xm_flags, idx;
byte[] structure_header, song_header; byte[] structure_header, song_header;
boolean delta_env; boolean delta_env;
String tracker_name; String tracker_name;
Instrument instrument; Instrument instrument;
Module module; Module module;
if( !is_xm( header_60_bytes ) ) { if( !is_xm( header_60_bytes ) ) {
throw new IllegalArgumentException( "Not an XM file!" ); throw new IllegalArgumentException( "Not an XM file!" );
} }
xm_version = unsigned_short_le( header_60_bytes, 58 ); xm_version = unsigned_short_le( header_60_bytes, 58 );
if( xm_version != 0x0104 ) { if( xm_version != 0x0104 ) {
throw new IllegalArgumentException( "Sorry, XM version " + xm_version + " is not supported!" ); throw new IllegalArgumentException( "Sorry, XM version " + xm_version + " is not supported!" );
} }
module = new Module(); module = new Module();
module.song_title = ascii_text( header_60_bytes, 17, 20 ); module.song_title = ascii_text( header_60_bytes, 17, 20 );
tracker_name = ascii_text( header_60_bytes, 38, 20 ); tracker_name = ascii_text( header_60_bytes, 38, 20 );
delta_env = tracker_name.startsWith( "DigiBooster Pro" ); delta_env = tracker_name.startsWith( "DigiBooster Pro" );
structure_header = new byte[ 4 ]; structure_header = new byte[ 4 ];
data_input.readFully( structure_header ); data_input.readFully( structure_header );
song_header_length = int_le( structure_header, 0 ); song_header_length = int_le( structure_header, 0 );
song_header = new byte[ song_header_length ]; song_header = new byte[ song_header_length ];
data_input.readFully( song_header, 4, song_header_length - 4 ); data_input.readFully( song_header, 4, song_header_length - 4 );
sequence_length = unsigned_short_le( song_header, 4 ); sequence_length = unsigned_short_le( song_header, 4 );
module.restart_sequence_index = unsigned_short_le( song_header, 6 ); module.restart_sequence_index = unsigned_short_le( song_header, 6 );
num_channels = unsigned_short_le( song_header, 8 ); num_channels = unsigned_short_le( song_header, 8 );
num_patterns = unsigned_short_le( song_header, 10 ); num_patterns = unsigned_short_le( song_header, 10 );
num_instruments = unsigned_short_le( song_header, 12 ); num_instruments = unsigned_short_le( song_header, 12 );
xm_flags = unsigned_short_le( song_header, 14 ); xm_flags = unsigned_short_le( song_header, 14 );
module.linear_periods = ( xm_flags & 0x1 ) == 0x1; module.linear_periods = ( xm_flags & 0x1 ) == 0x1;
module.global_volume = 64; module.global_volume = 64;
module.channel_gain = IBXM.FP_ONE * 3 / 8; module.channel_gain = IBXM.FP_ONE * 3 / 8;
module.default_speed = unsigned_short_le( song_header, 16 ); module.default_speed = unsigned_short_le( song_header, 16 );
module.default_tempo = unsigned_short_le( song_header, 18 ); module.default_tempo = unsigned_short_le( song_header, 18 );
module.set_num_channels( num_channels ); module.set_num_channels( num_channels );
for( idx = 0; idx < num_channels; idx++ ) { for( idx = 0; idx < num_channels; idx++ ) {
module.set_initial_panning( idx, 128 ); module.set_initial_panning( idx, 128 );
} }
module.set_sequence_length( sequence_length ); module.set_sequence_length( sequence_length );
for( idx = 0; idx < sequence_length; idx++ ) { for( idx = 0; idx < sequence_length; idx++ ) {
module.set_sequence( idx, song_header[ 20 + idx ] & 0xFF ); module.set_sequence( idx, song_header[ 20 + idx ] & 0xFF );
} }
module.set_num_patterns( num_patterns ); module.set_num_patterns( num_patterns );
for( idx = 0; idx < num_patterns; idx++ ) { for( idx = 0; idx < num_patterns; idx++ ) {
module.set_pattern( idx, read_xm_pattern( data_input, num_channels ) ); module.set_pattern( idx, read_xm_pattern( data_input, num_channels ) );
} }
module.set_num_instruments( num_instruments ); module.set_num_instruments( num_instruments );
for( idx = 1; idx <= num_instruments; idx++ ) { for( idx = 1; idx <= num_instruments; idx++ ) {
try { try {
instrument = read_xm_instrument( data_input, delta_env ); instrument = read_xm_instrument( data_input, delta_env );
module.set_instrument( idx, instrument ); module.set_instrument( idx, instrument );
} catch( EOFException e ) { } catch( EOFException e ) {
System.out.println( "Instrument " + idx + " is missing!" ); System.out.println( "Instrument " + idx + " is missing!" );
} }
} }
return module; return module;
} }
private static Pattern read_xm_pattern( DataInput data_input, int num_channels ) throws IOException { private static Pattern read_xm_pattern( DataInput data_input, int num_channels ) throws IOException {
int pattern_header_length, packing_type, num_rows, pattern_data_length; int pattern_header_length, packing_type, num_rows, pattern_data_length;
byte[] structure_header, pattern_header, pattern_data; byte[] structure_header, pattern_header, pattern_data;
Pattern pattern; Pattern pattern;
structure_header = new byte[ 4 ]; structure_header = new byte[ 4 ];
data_input.readFully( structure_header ); data_input.readFully( structure_header );
pattern_header_length = int_le( structure_header, 0 ); pattern_header_length = int_le( structure_header, 0 );
pattern_header = new byte[ pattern_header_length ]; pattern_header = new byte[ pattern_header_length ];
data_input.readFully( pattern_header, 4, pattern_header_length - 4 ); data_input.readFully( pattern_header, 4, pattern_header_length - 4 );
packing_type = pattern_header[ 4 ]; packing_type = pattern_header[ 4 ];
if( packing_type != 0 ) { if( packing_type != 0 ) {
throw new IllegalArgumentException( "Pattern packing type " + packing_type + " is not supported!" ); throw new IllegalArgumentException( "Pattern packing type " + packing_type + " is not supported!" );
} }
pattern = new Pattern(); pattern = new Pattern();
pattern.num_rows = unsigned_short_le( pattern_header, 5 ); pattern.num_rows = unsigned_short_le( pattern_header, 5 );
pattern_data_length = unsigned_short_le( pattern_header, 7 ); pattern_data_length = unsigned_short_le( pattern_header, 7 );
pattern_data = new byte[ pattern_data_length ]; pattern_data = new byte[ pattern_data_length ];
data_input.readFully( pattern_data ); data_input.readFully( pattern_data );
pattern.set_pattern_data( pattern_data ); pattern.set_pattern_data( pattern_data );
return pattern; return pattern;
} }
private static Instrument read_xm_instrument( DataInput data_input, boolean delta_env ) throws IOException { private static Instrument read_xm_instrument( DataInput data_input, boolean delta_env ) throws IOException {
int instrument_header_length, num_samples, idx; int instrument_header_length, num_samples, idx;
int env_tick, env_ampl, env_num_points, flags; int env_tick, env_ampl, env_num_points, flags;
byte[] structure_header, instrument_header, sample_headers; byte[] structure_header, instrument_header, sample_headers;
Instrument instrument; Instrument instrument;
Envelope envelope; Envelope envelope;
structure_header = new byte[ 4 ]; structure_header = new byte[ 4 ];
data_input.readFully( structure_header ); data_input.readFully( structure_header );
instrument_header_length = int_le( structure_header, 0 ); instrument_header_length = int_le( structure_header, 0 );
instrument_header = new byte[ instrument_header_length ]; instrument_header = new byte[ instrument_header_length ];
data_input.readFully( instrument_header, 4, instrument_header_length - 4 ); data_input.readFully( instrument_header, 4, instrument_header_length - 4 );
instrument = new Instrument(); instrument = new Instrument();
instrument.name = ascii_text( instrument_header, 4, 22 ); instrument.name = ascii_text( instrument_header, 4, 22 );
num_samples = unsigned_short_le( instrument_header, 27 ); num_samples = unsigned_short_le( instrument_header, 27 );
if( num_samples > 0 ) { if( num_samples > 0 ) {
instrument.set_num_samples( num_samples ); instrument.set_num_samples( num_samples );
for( idx = 0; idx < 96; idx++ ) { for( idx = 0; idx < 96; idx++ ) {
instrument.set_key_to_sample( idx + 1, instrument_header[ 33 + idx ] & 0xFF ); instrument.set_key_to_sample( idx + 1, instrument_header[ 33 + idx ] & 0xFF );
} }
envelope = new Envelope(); envelope = new Envelope();
env_num_points = instrument_header[ 225 ] & 0xFF; env_num_points = instrument_header[ 225 ] & 0xFF;
envelope.set_num_points( env_num_points ); envelope.set_num_points( env_num_points );
for( idx = 0; idx < env_num_points; idx++ ) { for( idx = 0; idx < env_num_points; idx++ ) {
env_tick = unsigned_short_le( instrument_header, 129 + idx * 4 ); env_tick = unsigned_short_le( instrument_header, 129 + idx * 4 );
env_ampl = unsigned_short_le( instrument_header, 131 + idx * 4 ); env_ampl = unsigned_short_le( instrument_header, 131 + idx * 4 );
envelope.set_point( idx, env_tick, env_ampl, delta_env ); envelope.set_point( idx, env_tick, env_ampl, delta_env );
} }
envelope.set_sustain_point( instrument_header[ 227 ] & 0xFF ); envelope.set_sustain_point( instrument_header[ 227 ] & 0xFF );
envelope.set_loop_points( instrument_header[ 228 ] & 0xFF, instrument_header[ 229 ] & 0xFF ); envelope.set_loop_points( instrument_header[ 228 ] & 0xFF, instrument_header[ 229 ] & 0xFF );
flags = instrument_header[ 233 ] & 0xFF; flags = instrument_header[ 233 ] & 0xFF;
instrument.volume_envelope_active = ( flags & 0x1 ) == 0x1; instrument.volume_envelope_active = ( flags & 0x1 ) == 0x1;
envelope.sustain = ( flags & 0x2 ) == 0x2; envelope.sustain = ( flags & 0x2 ) == 0x2;
envelope.looped = ( flags & 0x4 ) == 0x4; envelope.looped = ( flags & 0x4 ) == 0x4;
instrument.set_volume_envelope( envelope ); instrument.set_volume_envelope( envelope );
envelope = new Envelope(); envelope = new Envelope();
env_num_points = instrument_header[ 226 ] & 0xFF; env_num_points = instrument_header[ 226 ] & 0xFF;
envelope.set_num_points( env_num_points ); envelope.set_num_points( env_num_points );
for( idx = 0; idx < env_num_points; idx++ ) { for( idx = 0; idx < env_num_points; idx++ ) {
env_tick = unsigned_short_le( instrument_header, 177 + idx * 4 ); env_tick = unsigned_short_le( instrument_header, 177 + idx * 4 );
env_ampl = unsigned_short_le( instrument_header, 179 + idx * 4 ); env_ampl = unsigned_short_le( instrument_header, 179 + idx * 4 );
envelope.set_point( idx, env_tick, env_ampl, delta_env ); envelope.set_point( idx, env_tick, env_ampl, delta_env );
} }
envelope.set_sustain_point( instrument_header[ 230 ] & 0xFF ); envelope.set_sustain_point( instrument_header[ 230 ] & 0xFF );
envelope.set_loop_points( instrument_header[ 231 ] & 0xFF, instrument_header[ 232 ] & 0xFF ); envelope.set_loop_points( instrument_header[ 231 ] & 0xFF, instrument_header[ 232 ] & 0xFF );
flags = instrument_header[ 234 ] & 0xFF; flags = instrument_header[ 234 ] & 0xFF;
instrument.panning_envelope_active = ( flags & 0x1 ) == 0x1; instrument.panning_envelope_active = ( flags & 0x1 ) == 0x1;
envelope.sustain = ( flags & 0x2 ) == 0x2; envelope.sustain = ( flags & 0x2 ) == 0x2;
envelope.looped = ( flags & 0x4 ) == 0x4; envelope.looped = ( flags & 0x4 ) == 0x4;
instrument.set_panning_envelope( envelope ); instrument.set_panning_envelope( envelope );
instrument.vibrato_type = instrument_header[ 235 ] & 0xFF; instrument.vibrato_type = instrument_header[ 235 ] & 0xFF;
instrument.vibrato_sweep = instrument_header[ 236 ] & 0xFF; instrument.vibrato_sweep = instrument_header[ 236 ] & 0xFF;
instrument.vibrato_depth = instrument_header[ 237 ] & 0xFF; instrument.vibrato_depth = instrument_header[ 237 ] & 0xFF;
instrument.vibrato_rate = instrument_header[ 238 ] & 0xFF; instrument.vibrato_rate = instrument_header[ 238 ] & 0xFF;
instrument.volume_fade_out = unsigned_short_le( instrument_header, 239 ); instrument.volume_fade_out = unsigned_short_le( instrument_header, 239 );
sample_headers = new byte[ num_samples * 40 ]; sample_headers = new byte[ num_samples * 40 ];
data_input.readFully( sample_headers ); data_input.readFully( sample_headers );
for( idx = 0; idx < num_samples; idx++ ) { for( idx = 0; idx < num_samples; idx++ ) {
instrument.set_sample( idx, read_xm_sample( sample_headers, idx, data_input ) ); instrument.set_sample( idx, read_xm_sample( sample_headers, idx, data_input ) );
} }
} }
return instrument; return instrument;
} }
private static Sample read_xm_sample( byte[] sample_headers, int sample_idx, DataInput data_input ) throws IOException { private static Sample read_xm_sample( byte[] sample_headers, int sample_idx, DataInput data_input ) throws IOException {
int header_offset, sample_length, loop_start, loop_length; int header_offset, sample_length, loop_start, loop_length;
int flags, in_idx, out_idx, sam, last_sam; int flags, in_idx, out_idx, sam, last_sam;
int fine_tune, relative_note; int fine_tune, relative_note;
boolean sixteen_bit, ping_pong; boolean sixteen_bit, ping_pong;
byte[] raw_sample_data; byte[] raw_sample_data;
short[] decoded_sample_data; short[] decoded_sample_data;
Sample sample; Sample sample;
header_offset = sample_idx * 40; header_offset = sample_idx * 40;
sample = new Sample(); sample = new Sample();
sample_length = int_le( sample_headers, header_offset ); sample_length = int_le( sample_headers, header_offset );
loop_start = int_le( sample_headers, header_offset + 4 ); loop_start = int_le( sample_headers, header_offset + 4 );
loop_length = int_le( sample_headers, header_offset + 8 ); loop_length = int_le( sample_headers, header_offset + 8 );
sample.volume = sample_headers[ header_offset + 12 ] & 0xFF; sample.volume = sample_headers[ header_offset + 12 ] & 0xFF;
fine_tune = sample_headers[ header_offset + 13 ]; fine_tune = sample_headers[ header_offset + 13 ];
fine_tune = ( fine_tune << IBXM.FP_SHIFT ) / 1536; fine_tune = ( fine_tune << IBXM.FP_SHIFT ) / 1536;
sample.set_panning = true; sample.set_panning = true;
flags = sample_headers[ header_offset + 14 ] & 0xFF; flags = sample_headers[ header_offset + 14 ] & 0xFF;
if( ( flags & 0x03 ) == 0 ) { if( ( flags & 0x03 ) == 0 ) {
loop_length = 0; loop_length = 0;
} }
ping_pong = ( flags & 0x02 ) == 0x02; ping_pong = ( flags & 0x02 ) == 0x02;
sixteen_bit = ( flags & 0x10 ) == 0x10; sixteen_bit = ( flags & 0x10 ) == 0x10;
sample.panning = sample_headers[ header_offset + 15 ] & 0xFF; sample.panning = sample_headers[ header_offset + 15 ] & 0xFF;
relative_note = sample_headers[ header_offset + 16 ]; relative_note = sample_headers[ header_offset + 16 ];
relative_note = ( relative_note << IBXM.FP_SHIFT ) / 12; relative_note = ( relative_note << IBXM.FP_SHIFT ) / 12;
sample.transpose = relative_note + fine_tune; sample.transpose = relative_note + fine_tune;
sample.name = ascii_text( sample_headers, header_offset + 18, 22 ); sample.name = ascii_text( sample_headers, header_offset + 18, 22 );
raw_sample_data = new byte[ sample_length ]; raw_sample_data = new byte[ sample_length ];
try { try {
data_input.readFully( raw_sample_data ); data_input.readFully( raw_sample_data );
} catch( EOFException e ) { } catch( EOFException e ) {
System.out.println( "Sample has been truncated!" ); System.out.println( "Sample has been truncated!" );
} }
in_idx = 0; in_idx = 0;
out_idx = 0; out_idx = 0;
sam = 0; sam = 0;
last_sam = 0; last_sam = 0;
if( sixteen_bit ) { if( sixteen_bit ) {
decoded_sample_data = new short[ sample_length >> 1 ]; decoded_sample_data = new short[ sample_length >> 1 ];
while( in_idx < raw_sample_data.length ) { while( in_idx < raw_sample_data.length ) {
sam = raw_sample_data[ in_idx ] & 0xFF; sam = raw_sample_data[ in_idx ] & 0xFF;
sam = sam | ( ( raw_sample_data[ in_idx + 1 ] & 0xFF ) << 8 ); sam = sam | ( ( raw_sample_data[ in_idx + 1 ] & 0xFF ) << 8 );
last_sam = last_sam + sam; last_sam = last_sam + sam;
decoded_sample_data[ out_idx ] = ( short ) last_sam; decoded_sample_data[ out_idx ] = ( short ) last_sam;
in_idx += 2; in_idx += 2;
out_idx += 1; out_idx += 1;
} }
sample.set_sample_data( decoded_sample_data, loop_start >> 1, loop_length >> 1, ping_pong ); sample.set_sample_data( decoded_sample_data, loop_start >> 1, loop_length >> 1, ping_pong );
} else { } else {
decoded_sample_data = new short[ sample_length ]; decoded_sample_data = new short[ sample_length ];
while( in_idx < raw_sample_data.length ) { while( in_idx < raw_sample_data.length ) {
sam = raw_sample_data[ in_idx ] & 0xFF; sam = raw_sample_data[ in_idx ] & 0xFF;
last_sam = last_sam + sam; last_sam = last_sam + sam;
decoded_sample_data[ out_idx ] = ( short ) ( last_sam << 8 ); decoded_sample_data[ out_idx ] = ( short ) ( last_sam << 8 );
in_idx += 1; in_idx += 1;
out_idx += 1; out_idx += 1;
} }
sample.set_sample_data( decoded_sample_data, loop_start, loop_length, ping_pong ); sample.set_sample_data( decoded_sample_data, loop_start, loop_length, ping_pong );
} }
return sample; return sample;
} }
private static int unsigned_short_le( byte[] buffer, int offset ) { private static int unsigned_short_le( byte[] buffer, int offset ) {
int value; int value;
value = buffer[ offset ] & 0xFF; value = buffer[ offset ] & 0xFF;
value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 ); value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 );
return value; return value;
} }
private static int int_le( byte[] buffer, int offset ) { private static int int_le( byte[] buffer, int offset ) {
int value; int value;
value = buffer[ offset ] & 0xFF; value = buffer[ offset ] & 0xFF;
value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 ); value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 );
value = value | ( ( buffer[ offset + 2 ] & 0xFF ) << 16 ); value = value | ( ( buffer[ offset + 2 ] & 0xFF ) << 16 );
value = value | ( ( buffer[ offset + 3 ] & 0x7F ) << 24 ); value = value | ( ( buffer[ offset + 3 ] & 0x7F ) << 24 );
return value; return value;
} }
private static String ascii_text( byte[] buffer, int offset, int length ) { private static String ascii_text( byte[] buffer, int offset, int length ) {
int idx, chr; int idx, chr;
byte[] string_buffer; byte[] string_buffer;
String string; String string;
string_buffer = new byte[ length ]; string_buffer = new byte[ length ];
for( idx = 0; idx < length; idx++ ) { for( idx = 0; idx < length; idx++ ) {
chr = buffer[ offset + idx ]; chr = buffer[ offset + idx ];
if( chr < 32 ) { if( chr < 32 ) {
chr = 32; chr = 32;
} }
string_buffer[ idx ] = ( byte ) chr; string_buffer[ idx ] = ( byte ) chr;
} }
try { try {
string = new String( string_buffer, 0, length, "ISO-8859-1" ); string = new String( string_buffer, 0, length, "ISO-8859-1" );
} catch( UnsupportedEncodingException e ) { } catch( UnsupportedEncodingException e ) {
string = ""; string = "";
} }
return string; return string;
} }
} }

View File

@ -1,343 +1,343 @@
package ibxm; package ibxm;
public class IBXM { public class IBXM {
public static final String VERSION = "ibxm alpha 51 (c)2008 mumart@gmail.com"; public static final String VERSION = "ibxm alpha 51 (c)2008 mumart@gmail.com";
public static final int FP_SHIFT = 15; public static final int FP_SHIFT = 15;
public static final int FP_ONE = 1 << FP_SHIFT; public static final int FP_ONE = 1 << FP_SHIFT;
public static final int FP_MASK = FP_ONE - 1; public static final int FP_MASK = FP_ONE - 1;
private int sampling_rate, resampling_quality, volume_ramp_length; private int sampling_rate, resampling_quality, volume_ramp_length;
private int tick_length_samples, current_tick_samples; private int tick_length_samples, current_tick_samples;
private int[] mixing_buffer, volume_ramp_buffer; private int[] mixing_buffer, volume_ramp_buffer;
private Module module; private Module module;
private Channel[] channels; private Channel[] channels;
private int[] global_volume, note; private int[] global_volume, note;
private int current_sequence_index, next_sequence_index; private int current_sequence_index, next_sequence_index;
private int current_row, next_row; private int current_row, next_row;
private int tick_counter, ticks_per_row; private int tick_counter, ticks_per_row;
private int pattern_loop_count, pattern_loop_channel; private int pattern_loop_count, pattern_loop_channel;
public IBXM( int sample_rate ) { public IBXM( int sample_rate ) {
/** MODIFIED 13 Oct 2009 by Paul Lamb **/ /** MODIFIED 13 Oct 2009 by Paul Lamb **/
// System.out.println( VERSION ); // System.out.println( VERSION );
/***************************************/ /***************************************/
if( sample_rate < 8000 ) { if( sample_rate < 8000 ) {
sample_rate = 8000; sample_rate = 8000;
} }
sampling_rate = sample_rate; sampling_rate = sample_rate;
volume_ramp_length = sampling_rate >> 10; volume_ramp_length = sampling_rate >> 10;
volume_ramp_buffer = new int[ volume_ramp_length * 2 ]; volume_ramp_buffer = new int[ volume_ramp_length * 2 ];
mixing_buffer = new int[ sampling_rate / 6 ]; mixing_buffer = new int[ sampling_rate / 6 ];
global_volume = new int[ 1 ]; global_volume = new int[ 1 ];
note = new int[ 5 ]; note = new int[ 5 ];
set_module( new Module() ); set_module( new Module() );
set_resampling_quality( 1 ); set_resampling_quality( 1 );
} }
public void set_module( Module m ) { public void set_module( Module m ) {
int channel_idx; int channel_idx;
module = m; module = m;
channels = new Channel[ module.get_num_channels() ]; channels = new Channel[ module.get_num_channels() ];
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ] = new Channel( module, sampling_rate, global_volume ); channels[ channel_idx ] = new Channel( module, sampling_rate, global_volume );
} }
set_sequence_index( 0, 0 ); set_sequence_index( 0, 0 );
} }
public void set_resampling_quality( int quality ) { public void set_resampling_quality( int quality ) {
resampling_quality = quality; resampling_quality = quality;
} }
public int calculate_song_duration() { public int calculate_song_duration() {
int song_duration; int song_duration;
set_sequence_index( 0, 0 ); set_sequence_index( 0, 0 );
next_tick(); next_tick();
song_duration = tick_length_samples; song_duration = tick_length_samples;
while( !next_tick() ) { while( !next_tick() ) {
song_duration += tick_length_samples; song_duration += tick_length_samples;
} }
set_sequence_index( 0, 0 ); set_sequence_index( 0, 0 );
return song_duration; return song_duration;
} }
public void set_sequence_index( int sequence_index, int row ) { public void set_sequence_index( int sequence_index, int row ) {
int channel_idx; int channel_idx;
global_volume[ 0 ] = 64; global_volume[ 0 ] = 64;
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ].reset(); channels[ channel_idx ].reset();
channels[ channel_idx ].set_panning( module.get_initial_panning( channel_idx ) ); channels[ channel_idx ].set_panning( module.get_initial_panning( channel_idx ) );
} }
set_global_volume( module.global_volume ); set_global_volume( module.global_volume );
set_speed( 6 ); set_speed( 6 );
set_speed( module.default_speed ); set_speed( module.default_speed );
set_tempo( 125 ); set_tempo( 125 );
set_tempo( module.default_tempo ); set_tempo( module.default_tempo );
pattern_loop_count = -1; pattern_loop_count = -1;
next_sequence_index = sequence_index; next_sequence_index = sequence_index;
next_row = row; next_row = row;
tick_counter = 0; tick_counter = 0;
current_tick_samples = tick_length_samples; current_tick_samples = tick_length_samples;
clear_vol_ramp_buffer(); clear_vol_ramp_buffer();
} }
public void seek( int sample_position ) { public void seek( int sample_position ) {
int idx; int idx;
set_sequence_index( 0, 0 ); set_sequence_index( 0, 0 );
next_tick(); next_tick();
while( sample_position > tick_length_samples ) { while( sample_position > tick_length_samples ) {
sample_position -= tick_length_samples; sample_position -= tick_length_samples;
next_tick(); next_tick();
} }
mix_tick(); mix_tick();
current_tick_samples = sample_position; current_tick_samples = sample_position;
} }
public void get_audio( byte[] output_buffer, int frames ) { public void get_audio( byte[] output_buffer, int frames ) {
int output_idx, mix_idx, mix_end, count, amplitude; int output_idx, mix_idx, mix_end, count, amplitude;
output_idx = 0; output_idx = 0;
while( frames > 0 ) { while( frames > 0 ) {
count = tick_length_samples - current_tick_samples; count = tick_length_samples - current_tick_samples;
if( count > frames ) { if( count > frames ) {
count = frames; count = frames;
} }
mix_idx = current_tick_samples << 1; mix_idx = current_tick_samples << 1;
mix_end = mix_idx + ( count << 1 ) - 1; mix_end = mix_idx + ( count << 1 ) - 1;
while( mix_idx <= mix_end ) { while( mix_idx <= mix_end ) {
amplitude = mixing_buffer[ mix_idx ]; amplitude = mixing_buffer[ mix_idx ];
if( amplitude > 32767 ) { if( amplitude > 32767 ) {
amplitude = 32767; amplitude = 32767;
} }
if( amplitude < -32768 ) { if( amplitude < -32768 ) {
amplitude = -32768; amplitude = -32768;
} }
output_buffer[ output_idx ] = ( byte ) ( amplitude >> 8 ); output_buffer[ output_idx ] = ( byte ) ( amplitude >> 8 );
output_buffer[ output_idx + 1 ] = ( byte ) ( amplitude & 0xFF ); output_buffer[ output_idx + 1 ] = ( byte ) ( amplitude & 0xFF );
output_idx += 2; output_idx += 2;
mix_idx += 1; mix_idx += 1;
} }
current_tick_samples = mix_idx >> 1; current_tick_samples = mix_idx >> 1;
frames -= count; frames -= count;
if( frames > 0 ) { if( frames > 0 ) {
next_tick(); next_tick();
mix_tick(); mix_tick();
current_tick_samples = 0; current_tick_samples = 0;
} }
} }
} }
private void mix_tick() { private void mix_tick() {
int channel_idx, mix_idx, mix_len; int channel_idx, mix_idx, mix_len;
mix_idx = 0; mix_idx = 0;
mix_len = tick_length_samples + volume_ramp_length << 1; mix_len = tick_length_samples + volume_ramp_length << 1;
while( mix_idx < mix_len ) { while( mix_idx < mix_len ) {
mixing_buffer[ mix_idx ] = 0; mixing_buffer[ mix_idx ] = 0;
mix_idx += 1; mix_idx += 1;
} }
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
mix_len = tick_length_samples + volume_ramp_length; mix_len = tick_length_samples + volume_ramp_length;
channels[ channel_idx ].resample( mixing_buffer, 0, mix_len, resampling_quality ); channels[ channel_idx ].resample( mixing_buffer, 0, mix_len, resampling_quality );
} }
volume_ramp(); volume_ramp();
} }
private boolean next_tick() { private boolean next_tick() {
int channel_idx; int channel_idx;
boolean song_end; boolean song_end;
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ].update_sample_idx( tick_length_samples ); channels[ channel_idx ].update_sample_idx( tick_length_samples );
} }
tick_counter -= 1; tick_counter -= 1;
if( tick_counter <= 0 ) { if( tick_counter <= 0 ) {
tick_counter = ticks_per_row; tick_counter = ticks_per_row;
song_end = next_row(); song_end = next_row();
} else { } else {
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
channels[ channel_idx ].tick(); channels[ channel_idx ].tick();
} }
song_end = false; song_end = false;
} }
return song_end; return song_end;
} }
private boolean next_row() { private boolean next_row() {
int channel_idx, effect, effect_param; int channel_idx, effect, effect_param;
boolean song_end; boolean song_end;
Pattern pattern; Pattern pattern;
song_end = false; song_end = false;
if( next_sequence_index < 0 ) { if( next_sequence_index < 0 ) {
/* Bad next sequence index.*/ /* Bad next sequence index.*/
next_sequence_index = 0; next_sequence_index = 0;
next_row = 0; next_row = 0;
} }
if( next_sequence_index >= module.get_sequence_length() ) { if( next_sequence_index >= module.get_sequence_length() ) {
/* End of sequence.*/ /* End of sequence.*/
song_end = true; song_end = true;
next_sequence_index = module.restart_sequence_index; next_sequence_index = module.restart_sequence_index;
if( next_sequence_index < 0 ) { if( next_sequence_index < 0 ) {
next_sequence_index = 0; next_sequence_index = 0;
} }
if( next_sequence_index >= module.get_sequence_length() ) { if( next_sequence_index >= module.get_sequence_length() ) {
next_sequence_index = 0; next_sequence_index = 0;
} }
next_row = 0; next_row = 0;
} }
if( next_sequence_index < current_sequence_index ) { if( next_sequence_index < current_sequence_index ) {
/* Jump to previous pattern. */ /* Jump to previous pattern. */
song_end = true; song_end = true;
} }
if( next_sequence_index == current_sequence_index ) { if( next_sequence_index == current_sequence_index ) {
if( next_row <= current_row ) { if( next_row <= current_row ) {
if( pattern_loop_count < 0 ) { if( pattern_loop_count < 0 ) {
/* Jump to previous row in the same pattern, but not a pattern loop. */ /* Jump to previous row in the same pattern, but not a pattern loop. */
song_end = true; song_end = true;
} }
} }
} }
current_sequence_index = next_sequence_index; current_sequence_index = next_sequence_index;
pattern = module.get_pattern_from_sequence( current_sequence_index ); pattern = module.get_pattern_from_sequence( current_sequence_index );
if( next_row < 0 || next_row >= pattern.num_rows ) { if( next_row < 0 || next_row >= pattern.num_rows ) {
/* Bad next row.*/ /* Bad next row.*/
next_row = 0; next_row = 0;
} }
current_row = next_row; current_row = next_row;
next_row = current_row + 1; next_row = current_row + 1;
if( next_row >= pattern.num_rows ) { if( next_row >= pattern.num_rows ) {
next_sequence_index = current_sequence_index + 1; next_sequence_index = current_sequence_index + 1;
next_row = 0; next_row = 0;
} }
for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) {
pattern.get_note( note, current_row * channels.length + channel_idx ); pattern.get_note( note, current_row * channels.length + channel_idx );
effect = note[ 3 ]; effect = note[ 3 ];
effect_param = note[ 4 ]; effect_param = note[ 4 ];
channels[ channel_idx ].row( note[ 0 ], note[ 1 ], note[ 2 ], effect, effect_param ); channels[ channel_idx ].row( note[ 0 ], note[ 1 ], note[ 2 ], effect, effect_param );
switch( effect ) { switch( effect ) {
case 0x0B: case 0x0B:
/* Pattern Jump.*/ /* Pattern Jump.*/
if( pattern_loop_count < 0 ) { if( pattern_loop_count < 0 ) {
next_sequence_index = effect_param; next_sequence_index = effect_param;
next_row = 0; next_row = 0;
} }
break; break;
case 0x0D: case 0x0D:
/* Pattern Break.*/ /* Pattern Break.*/
if( pattern_loop_count < 0 ) { if( pattern_loop_count < 0 ) {
next_sequence_index = current_sequence_index + 1; next_sequence_index = current_sequence_index + 1;
next_row = ( effect_param >> 4 ) * 10 + ( effect_param & 0x0F ); next_row = ( effect_param >> 4 ) * 10 + ( effect_param & 0x0F );
} }
break; break;
case 0x0E: case 0x0E:
/* Extended.*/ /* Extended.*/
switch( effect_param & 0xF0 ) { switch( effect_param & 0xF0 ) {
case 0x60: case 0x60:
/* Pattern loop.*/ /* Pattern loop.*/
if( ( effect_param & 0x0F ) == 0 ) { if( ( effect_param & 0x0F ) == 0 ) {
/* Set loop marker on this channel. */ /* Set loop marker on this channel. */
channels[ channel_idx ].pattern_loop_row = current_row; channels[ channel_idx ].pattern_loop_row = current_row;
} }
if( channels[ channel_idx ].pattern_loop_row < current_row ) { if( channels[ channel_idx ].pattern_loop_row < current_row ) {
/* Marker and parameter are valid. Begin looping. */ /* Marker and parameter are valid. Begin looping. */
if( pattern_loop_count < 0 ) { if( pattern_loop_count < 0 ) {
/* Not already looping, begin. */ /* Not already looping, begin. */
pattern_loop_count = effect_param & 0x0F; pattern_loop_count = effect_param & 0x0F;
pattern_loop_channel = channel_idx; pattern_loop_channel = channel_idx;
} }
if( pattern_loop_channel == channel_idx ) { if( pattern_loop_channel == channel_idx ) {
/* Loop in progress on this channel. Next iteration. */ /* Loop in progress on this channel. Next iteration. */
if( pattern_loop_count == 0 ) { if( pattern_loop_count == 0 ) {
/* Loop finished. */ /* Loop finished. */
/* Invalidate current marker. */ /* Invalidate current marker. */
channels[ channel_idx ].pattern_loop_row = current_row + 1; channels[ channel_idx ].pattern_loop_row = current_row + 1;
} else { } else {
/* Count must be higher than zero. */ /* Count must be higher than zero. */
/* Loop and cancel any breaks on this row. */ /* Loop and cancel any breaks on this row. */
next_row = channels[ channel_idx ].pattern_loop_row; next_row = channels[ channel_idx ].pattern_loop_row;
next_sequence_index = current_sequence_index; next_sequence_index = current_sequence_index;
} }
pattern_loop_count -= 1; pattern_loop_count -= 1;
} }
} }
break; break;
case 0xE0: case 0xE0:
/* Pattern delay.*/ /* Pattern delay.*/
tick_counter += ticks_per_row * ( effect_param & 0x0F ); tick_counter += ticks_per_row * ( effect_param & 0x0F );
break; break;
} }
break; break;
case 0x0F: case 0x0F:
/* Set Speed/Tempo.*/ /* Set Speed/Tempo.*/
if( effect_param < 32 ) { if( effect_param < 32 ) {
set_speed( effect_param ); set_speed( effect_param );
tick_counter = ticks_per_row; tick_counter = ticks_per_row;
} else { } else {
set_tempo( effect_param ); set_tempo( effect_param );
} }
break; break;
case 0x25: case 0x25:
/* S3M Set Speed.*/ /* S3M Set Speed.*/
set_speed( effect_param ); set_speed( effect_param );
tick_counter = ticks_per_row; tick_counter = ticks_per_row;
break; break;
} }
} }
return song_end; return song_end;
} }
private void set_global_volume( int volume ) { private void set_global_volume( int volume ) {
if( volume < 0 ) { if( volume < 0 ) {
volume = 0; volume = 0;
} }
if( volume > 64 ) { if( volume > 64 ) {
volume = 64; volume = 64;
} }
global_volume[ 0 ] = volume; global_volume[ 0 ] = volume;
} }
private void set_speed( int speed ) { private void set_speed( int speed ) {
if( speed > 0 && speed < 256 ) { if( speed > 0 && speed < 256 ) {
ticks_per_row = speed; ticks_per_row = speed;
} }
} }
private void set_tempo( int bpm ) { private void set_tempo( int bpm ) {
if( bpm > 31 && bpm < 256 ) { if( bpm > 31 && bpm < 256 ) {
tick_length_samples = ( sampling_rate * 5 ) / ( bpm * 2 ); tick_length_samples = ( sampling_rate * 5 ) / ( bpm * 2 );
} }
} }
private void volume_ramp() { private void volume_ramp() {
int ramp_idx, next_idx, ramp_end; int ramp_idx, next_idx, ramp_end;
int volume_ramp_delta, volume, sample; int volume_ramp_delta, volume, sample;
sample = 0; sample = 0;
volume_ramp_delta = FP_ONE / volume_ramp_length; volume_ramp_delta = FP_ONE / volume_ramp_length;
volume = 0; volume = 0;
ramp_idx = 0; ramp_idx = 0;
next_idx = 2 * tick_length_samples; next_idx = 2 * tick_length_samples;
ramp_end = volume_ramp_length * 2 - 1; ramp_end = volume_ramp_length * 2 - 1;
while( ramp_idx <= ramp_end ) { while( ramp_idx <= ramp_end ) {
sample = volume_ramp_buffer[ ramp_idx ] * ( FP_ONE - volume ) >> FP_SHIFT; sample = volume_ramp_buffer[ ramp_idx ] * ( FP_ONE - volume ) >> FP_SHIFT;
mixing_buffer[ ramp_idx ] = sample + ( mixing_buffer[ ramp_idx ] * volume >> FP_SHIFT ); mixing_buffer[ ramp_idx ] = sample + ( mixing_buffer[ ramp_idx ] * volume >> FP_SHIFT );
volume_ramp_buffer[ ramp_idx ] = mixing_buffer[ next_idx + ramp_idx ]; volume_ramp_buffer[ ramp_idx ] = mixing_buffer[ next_idx + ramp_idx ];
sample = volume_ramp_buffer[ ramp_idx + 1 ] * ( FP_ONE - volume ) >> FP_SHIFT; sample = volume_ramp_buffer[ ramp_idx + 1 ] * ( FP_ONE - volume ) >> FP_SHIFT;
mixing_buffer[ ramp_idx + 1 ] = sample + ( mixing_buffer[ ramp_idx + 1 ] * volume >> FP_SHIFT ); mixing_buffer[ ramp_idx + 1 ] = sample + ( mixing_buffer[ ramp_idx + 1 ] * volume >> FP_SHIFT );
volume_ramp_buffer[ ramp_idx + 1 ] = mixing_buffer[ next_idx + ramp_idx + 1 ]; volume_ramp_buffer[ ramp_idx + 1 ] = mixing_buffer[ next_idx + ramp_idx + 1 ];
volume += volume_ramp_delta; volume += volume_ramp_delta;
ramp_idx += 2; ramp_idx += 2;
} }
} }
private void clear_vol_ramp_buffer() { private void clear_vol_ramp_buffer() {
int ramp_idx, ramp_end; int ramp_idx, ramp_end;
ramp_idx = 0; ramp_idx = 0;
ramp_end = volume_ramp_length * 2 - 1; ramp_end = volume_ramp_length * 2 - 1;
while( ramp_idx <= ramp_end ) { while( ramp_idx <= ramp_end ) {
volume_ramp_buffer[ ramp_idx ] = 0; volume_ramp_buffer[ ramp_idx ] = 0;
ramp_idx += 1; ramp_idx += 1;
} }
} }
} }

View File

@ -1,90 +1,90 @@
package ibxm; package ibxm;
public class Instrument { public class Instrument {
public String name; public String name;
public int vibrato_type, vibrato_sweep; public int vibrato_type, vibrato_sweep;
public int vibrato_depth, vibrato_rate; public int vibrato_depth, vibrato_rate;
public boolean volume_envelope_active, panning_envelope_active; public boolean volume_envelope_active, panning_envelope_active;
public int volume_fade_out; public int volume_fade_out;
private Envelope volume_envelope, panning_envelope; private Envelope volume_envelope, panning_envelope;
private int[] key_to_sample; private int[] key_to_sample;
private Sample[] samples; private Sample[] samples;
public Instrument() { public Instrument() {
name = ""; name = "";
set_volume_envelope( new Envelope() ); set_volume_envelope( new Envelope() );
set_panning_envelope( new Envelope() ); set_panning_envelope( new Envelope() );
key_to_sample = new int[ 96 ]; key_to_sample = new int[ 96 ];
set_num_samples( 1 ); set_num_samples( 1 );
} }
public Envelope get_volume_envelope() { public Envelope get_volume_envelope() {
return volume_envelope; return volume_envelope;
} }
public void set_volume_envelope( Envelope envelope ) { public void set_volume_envelope( Envelope envelope ) {
if( envelope != null ) { if( envelope != null ) {
volume_envelope = envelope; volume_envelope = envelope;
} }
} }
public Envelope get_panning_envelope() { public Envelope get_panning_envelope() {
return panning_envelope; return panning_envelope;
} }
public void set_panning_envelope( Envelope envelope ) { public void set_panning_envelope( Envelope envelope ) {
if( envelope != null ) { if( envelope != null ) {
panning_envelope = envelope; panning_envelope = envelope;
} }
} }
public Sample get_sample_from_key( int key ) { public Sample get_sample_from_key( int key ) {
int sample_idx; int sample_idx;
sample_idx = 0; sample_idx = 0;
if( key > 0 && key <= key_to_sample.length ) { if( key > 0 && key <= key_to_sample.length ) {
sample_idx = key_to_sample[ key - 1 ]; sample_idx = key_to_sample[ key - 1 ];
} }
return get_sample( sample_idx ); return get_sample( sample_idx );
} }
public void set_key_to_sample( int key, int sample ) { public void set_key_to_sample( int key, int sample ) {
if( key > 0 && key <= key_to_sample.length ) { if( key > 0 && key <= key_to_sample.length ) {
key_to_sample[ key - 1 ] = sample; key_to_sample[ key - 1 ] = sample;
} }
} }
public int get_num_samples() { public int get_num_samples() {
return samples.length; return samples.length;
} }
public void set_num_samples( int num_samples ) { public void set_num_samples( int num_samples ) {
if( num_samples < 1 ) { if( num_samples < 1 ) {
num_samples = 1; num_samples = 1;
} }
samples = new Sample[ num_samples ]; samples = new Sample[ num_samples ];
set_sample( 0, null ); set_sample( 0, null );
} }
public Sample get_sample( int sample_index ) { public Sample get_sample( int sample_index ) {
Sample sample; Sample sample;
sample = null; sample = null;
if( sample_index >= 0 && sample_index < samples.length ) { if( sample_index >= 0 && sample_index < samples.length ) {
sample = samples[ sample_index ]; sample = samples[ sample_index ];
} }
if( sample == null ) { if( sample == null ) {
sample = samples[ 0 ]; sample = samples[ 0 ];
} }
return sample; return sample;
} }
public void set_sample( int sample_index, Sample sample ) { public void set_sample( int sample_index, Sample sample ) {
if( sample_index >= 0 && sample_index < samples.length ) { if( sample_index >= 0 && sample_index < samples.length ) {
samples[ sample_index ] = sample; samples[ sample_index ] = sample;
} }
if( samples[ 0 ] == null ) { if( samples[ 0 ] == null ) {
samples[ 0 ] = new Sample(); samples[ 0 ] = new Sample();
} }
} }
} }

View File

@ -1,91 +1,91 @@
package ibxm; package ibxm;
/* /*
Base-2 Log and Exp functions, using linear-interpolated tables. Base-2 Log and Exp functions, using linear-interpolated tables.
*/ */
public class LogTable { public class LogTable {
private static final int TABLE_SHIFT = 7; // 128 points (+1 for interp) private static final int TABLE_SHIFT = 7; // 128 points (+1 for interp)
private static final int INTERP_SHIFT = IBXM.FP_SHIFT - TABLE_SHIFT; private static final int INTERP_SHIFT = IBXM.FP_SHIFT - TABLE_SHIFT;
private static final int INTERP_MASK = ( 1 << INTERP_SHIFT ) - 1; private static final int INTERP_MASK = ( 1 << INTERP_SHIFT ) - 1;
private static final int[] exp_2_table = { private static final int[] exp_2_table = {
32768, 32945, 33124, 33304, 33485, 33667, 33850, 34033, 32768, 32945, 33124, 33304, 33485, 33667, 33850, 34033,
34218, 34404, 34591, 34779, 34968, 35157, 35348, 35540, 34218, 34404, 34591, 34779, 34968, 35157, 35348, 35540,
35733, 35927, 36122, 36319, 36516, 36714, 36913, 37114, 35733, 35927, 36122, 36319, 36516, 36714, 36913, 37114,
37315, 37518, 37722, 37926, 38132, 38339, 38548, 38757, 37315, 37518, 37722, 37926, 38132, 38339, 38548, 38757,
38967, 39179, 39392, 39606, 39821, 40037, 40254, 40473, 38967, 39179, 39392, 39606, 39821, 40037, 40254, 40473,
40693, 40914, 41136, 41359, 41584, 41810, 42037, 42265, 40693, 40914, 41136, 41359, 41584, 41810, 42037, 42265,
42494, 42725, 42957, 43190, 43425, 43661, 43898, 44136, 42494, 42725, 42957, 43190, 43425, 43661, 43898, 44136,
44376, 44617, 44859, 45103, 45347, 45594, 45841, 46090, 44376, 44617, 44859, 45103, 45347, 45594, 45841, 46090,
46340, 46592, 46845, 47099, 47355, 47612, 47871, 48131, 46340, 46592, 46845, 47099, 47355, 47612, 47871, 48131,
48392, 48655, 48919, 49185, 49452, 49720, 49990, 50262, 48392, 48655, 48919, 49185, 49452, 49720, 49990, 50262,
50535, 50809, 51085, 51362, 51641, 51922, 52204, 52487, 50535, 50809, 51085, 51362, 51641, 51922, 52204, 52487,
52772, 53059, 53347, 53636, 53928, 54220, 54515, 54811, 52772, 53059, 53347, 53636, 53928, 54220, 54515, 54811,
55108, 55408, 55709, 56011, 56315, 56621, 56928, 57238, 55108, 55408, 55709, 56011, 56315, 56621, 56928, 57238,
57548, 57861, 58175, 58491, 58809, 59128, 59449, 59772, 57548, 57861, 58175, 58491, 58809, 59128, 59449, 59772,
60096, 60423, 60751, 61081, 61412, 61746, 62081, 62418, 60096, 60423, 60751, 61081, 61412, 61746, 62081, 62418,
62757, 63098, 63440, 63785, 64131, 64479, 64830, 65182, 62757, 63098, 63440, 63785, 64131, 64479, 64830, 65182,
65536 65536
}; };
private static final int[] log_2_table = { private static final int[] log_2_table = {
0, 367, 732, 1095, 1454, 1811, 2165, 2517, 0, 367, 732, 1095, 1454, 1811, 2165, 2517,
2865, 3212, 3556, 3897, 4236, 4572, 4906, 5238, 2865, 3212, 3556, 3897, 4236, 4572, 4906, 5238,
5568, 5895, 6220, 6542, 6863, 7181, 7497, 7812, 5568, 5895, 6220, 6542, 6863, 7181, 7497, 7812,
8124, 8434, 8742, 9048, 9352, 9654, 9954, 10252, 8124, 8434, 8742, 9048, 9352, 9654, 9954, 10252,
10548, 10843, 11136, 11427, 11716, 12003, 12289, 12573, 10548, 10843, 11136, 11427, 11716, 12003, 12289, 12573,
12855, 13136, 13414, 13692, 13967, 14241, 14514, 14785, 12855, 13136, 13414, 13692, 13967, 14241, 14514, 14785,
15054, 15322, 15588, 15853, 16117, 16378, 16639, 16898, 15054, 15322, 15588, 15853, 16117, 16378, 16639, 16898,
17156, 17412, 17667, 17920, 18172, 18423, 18673, 18921, 17156, 17412, 17667, 17920, 18172, 18423, 18673, 18921,
19168, 19413, 19657, 19900, 20142, 20383, 20622, 20860, 19168, 19413, 19657, 19900, 20142, 20383, 20622, 20860,
21097, 21333, 21568, 21801, 22034, 22265, 22495, 22724, 21097, 21333, 21568, 21801, 22034, 22265, 22495, 22724,
22952, 23178, 23404, 23628, 23852, 24074, 24296, 24516, 22952, 23178, 23404, 23628, 23852, 24074, 24296, 24516,
24736, 24954, 25171, 25388, 25603, 25817, 26031, 26243, 24736, 24954, 25171, 25388, 25603, 25817, 26031, 26243,
26455, 26665, 26875, 27084, 27292, 27499, 27705, 27910, 26455, 26665, 26875, 27084, 27292, 27499, 27705, 27910,
28114, 28317, 28520, 28721, 28922, 29122, 29321, 29519, 28114, 28317, 28520, 28721, 28922, 29122, 29321, 29519,
29716, 29913, 30109, 30304, 30498, 30691, 30884, 31076, 29716, 29913, 30109, 30304, 30498, 30691, 30884, 31076,
31267, 31457, 31646, 31835, 32023, 32210, 32397, 32582, 31267, 31457, 31646, 31835, 32023, 32210, 32397, 32582,
32768 32768
}; };
/* /*
Calculate log-base-2 of x (non-fixed-point). Calculate log-base-2 of x (non-fixed-point).
A fixed point value is returned. A fixed point value is returned.
*/ */
public static int log_2( int x ) { public static int log_2( int x ) {
int shift; int shift;
/* Scale x to range 1.0 <= x < 2.0 */ /* Scale x to range 1.0 <= x < 2.0 */
shift = IBXM.FP_SHIFT; shift = IBXM.FP_SHIFT;
while( x < IBXM.FP_ONE ) { while( x < IBXM.FP_ONE ) {
x <<= 1; x <<= 1;
shift--; shift--;
} }
while( x >= ( IBXM.FP_ONE << 1 ) ) { while( x >= ( IBXM.FP_ONE << 1 ) ) {
x >>= 1; x >>= 1;
shift++; shift++;
} }
return ( IBXM.FP_ONE * shift ) + eval_table( log_2_table, x - IBXM.FP_ONE ); return ( IBXM.FP_ONE * shift ) + eval_table( log_2_table, x - IBXM.FP_ONE );
} }
/* /*
Raise 2 to the power x (fixed point). Raise 2 to the power x (fixed point).
A fixed point value is returned. A fixed point value is returned.
*/ */
public static int raise_2( int x ) { public static int raise_2( int x ) {
int y; int y;
y = eval_table( exp_2_table, x & IBXM.FP_MASK ) << IBXM.FP_SHIFT; y = eval_table( exp_2_table, x & IBXM.FP_MASK ) << IBXM.FP_SHIFT;
return y >> IBXM.FP_SHIFT - ( x >> IBXM.FP_SHIFT ); return y >> IBXM.FP_SHIFT - ( x >> IBXM.FP_SHIFT );
} }
private static int eval_table( int[] table, int x ) { private static int eval_table( int[] table, int x ) {
int table_idx, table_frac, c, m, y; int table_idx, table_frac, c, m, y;
table_idx = x >> INTERP_SHIFT; table_idx = x >> INTERP_SHIFT;
table_frac = x & INTERP_MASK; table_frac = x & INTERP_MASK;
c = table[ table_idx ]; c = table[ table_idx ];
m = table[ table_idx + 1 ] - c; m = table[ table_idx + 1 ] - c;
y = ( m * table_frac >> INTERP_SHIFT ) + c; y = ( m * table_frac >> INTERP_SHIFT ) + c;
return y >> 15 - IBXM.FP_SHIFT; return y >> 15 - IBXM.FP_SHIFT;
} }
} }

View File

@ -1,138 +1,138 @@
package ibxm; package ibxm;
public class Module { public class Module {
public String song_title; public String song_title;
public boolean linear_periods, fast_volume_slides, pal; public boolean linear_periods, fast_volume_slides, pal;
public int global_volume, channel_gain; public int global_volume, channel_gain;
public int default_speed, default_tempo; public int default_speed, default_tempo;
public int restart_sequence_index; public int restart_sequence_index;
private int[] initial_panning, sequence; private int[] initial_panning, sequence;
private Pattern[] patterns; private Pattern[] patterns;
private Instrument[] instruments; private Instrument[] instruments;
private Pattern default_pattern; private Pattern default_pattern;
private Instrument default_instrument; private Instrument default_instrument;
public Module() { public Module() {
song_title = IBXM.VERSION; song_title = IBXM.VERSION;
set_num_channels( 1 ); set_num_channels( 1 );
set_sequence_length( 1 ); set_sequence_length( 1 );
set_num_patterns( 0 ); set_num_patterns( 0 );
set_num_instruments( 0 ); set_num_instruments( 0 );
default_pattern = new Pattern(); default_pattern = new Pattern();
default_instrument = new Instrument(); default_instrument = new Instrument();
} }
public int get_num_channels() { public int get_num_channels() {
return initial_panning.length; return initial_panning.length;
} }
public void set_num_channels( int num_channels ) { public void set_num_channels( int num_channels ) {
if( num_channels < 1 ) { if( num_channels < 1 ) {
num_channels = 1; num_channels = 1;
} }
initial_panning = new int[ num_channels ]; initial_panning = new int[ num_channels ];
} }
public int get_initial_panning( int channel ) { public int get_initial_panning( int channel ) {
int panning; int panning;
panning = 128; panning = 128;
if( channel >= 0 && channel < initial_panning.length ) { if( channel >= 0 && channel < initial_panning.length ) {
panning = initial_panning[ channel ]; panning = initial_panning[ channel ];
} }
return panning; return panning;
} }
public void set_initial_panning( int channel, int panning ) { public void set_initial_panning( int channel, int panning ) {
if( channel >= 0 && channel < initial_panning.length ) { if( channel >= 0 && channel < initial_panning.length ) {
initial_panning[ channel ] = panning; initial_panning[ channel ] = panning;
} }
} }
public int get_sequence_length() { public int get_sequence_length() {
return sequence.length; return sequence.length;
} }
public void set_sequence_length( int sequence_length ) { public void set_sequence_length( int sequence_length ) {
if( sequence_length < 0 ) { if( sequence_length < 0 ) {
sequence_length = 0; sequence_length = 0;
} }
sequence = new int[ sequence_length ]; sequence = new int[ sequence_length ];
} }
public void set_sequence( int sequence_index, int pattern_index ) { public void set_sequence( int sequence_index, int pattern_index ) {
if( sequence_index >= 0 && sequence_index < sequence.length ) { if( sequence_index >= 0 && sequence_index < sequence.length ) {
sequence[ sequence_index ] = pattern_index; sequence[ sequence_index ] = pattern_index;
} }
} }
public int get_num_patterns() { public int get_num_patterns() {
return patterns.length; return patterns.length;
} }
public void set_num_patterns( int num_patterns ) { public void set_num_patterns( int num_patterns ) {
if( num_patterns < 0 ) { if( num_patterns < 0 ) {
num_patterns = 0; num_patterns = 0;
} }
patterns = new Pattern[ num_patterns ]; patterns = new Pattern[ num_patterns ];
} }
public Pattern get_pattern_from_sequence( int sequence_index ) { public Pattern get_pattern_from_sequence( int sequence_index ) {
Pattern pattern; Pattern pattern;
pattern = default_pattern; pattern = default_pattern;
if( sequence_index >= 0 && sequence_index < sequence.length ) { if( sequence_index >= 0 && sequence_index < sequence.length ) {
pattern = get_pattern( sequence[ sequence_index ] ); pattern = get_pattern( sequence[ sequence_index ] );
} }
return pattern; return pattern;
} }
public Pattern get_pattern( int pattern_index ) { public Pattern get_pattern( int pattern_index ) {
Pattern pattern; Pattern pattern;
pattern = null; pattern = null;
if( pattern_index >= 0 && pattern_index < patterns.length ) { if( pattern_index >= 0 && pattern_index < patterns.length ) {
pattern = patterns[ pattern_index ]; pattern = patterns[ pattern_index ];
} }
if( pattern == null ) { if( pattern == null ) {
pattern = default_pattern; pattern = default_pattern;
} }
return pattern; return pattern;
} }
public void set_pattern( int pattern_index, Pattern pattern ) { public void set_pattern( int pattern_index, Pattern pattern ) {
if( pattern_index >= 0 && pattern_index < patterns.length ) { if( pattern_index >= 0 && pattern_index < patterns.length ) {
patterns[ pattern_index ] = pattern; patterns[ pattern_index ] = pattern;
} }
} }
public int get_num_instruments() { public int get_num_instruments() {
return instruments.length; return instruments.length;
} }
public void set_num_instruments( int num_instruments ) { public void set_num_instruments( int num_instruments ) {
if( num_instruments < 0 ) { if( num_instruments < 0 ) {
num_instruments = 0; num_instruments = 0;
} }
instruments = new Instrument[ num_instruments ]; instruments = new Instrument[ num_instruments ];
} }
public Instrument get_instrument( int instrument_index ) { public Instrument get_instrument( int instrument_index ) {
Instrument instrument; Instrument instrument;
instrument = null; instrument = null;
if( instrument_index > 0 && instrument_index <= instruments.length ) { if( instrument_index > 0 && instrument_index <= instruments.length ) {
instrument = instruments[ instrument_index - 1 ]; instrument = instruments[ instrument_index - 1 ];
} }
if( instrument == null ) { if( instrument == null ) {
instrument = default_instrument; instrument = default_instrument;
} }
return instrument; return instrument;
} }
public void set_instrument( int instrument_index, Instrument instrument ) { public void set_instrument( int instrument_index, Instrument instrument ) {
if( instrument_index > 0 && instrument_index <= instruments.length ) { if( instrument_index > 0 && instrument_index <= instruments.length ) {
instruments[ instrument_index - 1 ] = instrument; instruments[ instrument_index - 1 ] = instrument;
} }
} }
} }

View File

@ -1,61 +1,61 @@
package ibxm; package ibxm;
public class Pattern { public class Pattern {
public int num_rows; public int num_rows;
private int data_offset, note_index; private int data_offset, note_index;
private byte[] pattern_data; private byte[] pattern_data;
public Pattern() { public Pattern() {
num_rows = 1; num_rows = 1;
set_pattern_data( new byte[ 0 ] ); set_pattern_data( new byte[ 0 ] );
} }
public void set_pattern_data( byte[] data ) { public void set_pattern_data( byte[] data ) {
if( data != null ) { if( data != null ) {
pattern_data = data; pattern_data = data;
} }
data_offset = 0; data_offset = 0;
note_index = 0; note_index = 0;
} }
public void get_note( int[] note, int index ) { public void get_note( int[] note, int index ) {
if( index < note_index ) { if( index < note_index ) {
note_index = 0; note_index = 0;
data_offset = 0; data_offset = 0;
} }
while( note_index <= index ) { while( note_index <= index ) {
data_offset = next_note( data_offset, note ); data_offset = next_note( data_offset, note );
note_index += 1; note_index += 1;
} }
} }
public int next_note( int data_offset, int[] note ) { public int next_note( int data_offset, int[] note ) {
int bitmask, field; int bitmask, field;
if( data_offset < 0 ) { if( data_offset < 0 ) {
data_offset = pattern_data.length; data_offset = pattern_data.length;
} }
bitmask = 0x80; bitmask = 0x80;
if( data_offset < pattern_data.length ) { if( data_offset < pattern_data.length ) {
bitmask = pattern_data[ data_offset ] & 0xFF; bitmask = pattern_data[ data_offset ] & 0xFF;
} }
if( ( bitmask & 0x80 ) == 0x80 ) { if( ( bitmask & 0x80 ) == 0x80 ) {
data_offset += 1; data_offset += 1;
} else { } else {
bitmask = 0x1F; bitmask = 0x1F;
} }
for( field = 0; field < 5; field++ ) { for( field = 0; field < 5; field++ ) {
note[ field ] = 0; note[ field ] = 0;
if( ( bitmask & 0x01 ) == 0x01 ) { if( ( bitmask & 0x01 ) == 0x01 ) {
if( data_offset < pattern_data.length ) { if( data_offset < pattern_data.length ) {
note[ field ] = pattern_data[ data_offset ] & 0xFF; note[ field ] = pattern_data[ data_offset ] & 0xFF;
data_offset += 1; data_offset += 1;
} }
} }
bitmask = bitmask >> 1; bitmask = bitmask >> 1;
} }
return data_offset; return data_offset;
} }
} }

View File

@ -1,132 +1,132 @@
package ibxm; package ibxm;
import java.io.*; import java.io.*;
import javax.sound.sampled.*; import javax.sound.sampled.*;
public class Player { public class Player {
private Thread play_thread; private Thread play_thread;
private IBXM ibxm; private IBXM ibxm;
private Module module; private Module module;
private int song_duration, play_position; private int song_duration, play_position;
private boolean running, loop; private boolean running, loop;
private byte[] output_buffer; private byte[] output_buffer;
private SourceDataLine output_line; private SourceDataLine output_line;
/** /**
Simple command-line test player. Simple command-line test player.
*/ */
public static void main( String[] args ) throws Exception { public static void main( String[] args ) throws Exception {
if( args.length < 1 ) { if( args.length < 1 ) {
System.err.println( "Usage: java ibxm.Player <module file>" ); System.err.println( "Usage: java ibxm.Player <module file>" );
System.exit( 0 ); System.exit( 0 );
} }
FileInputStream file_input_stream = new FileInputStream( args[ 0 ] ); FileInputStream file_input_stream = new FileInputStream( args[ 0 ] );
Player player = new Player(); Player player = new Player();
player.set_module( Player.load_module( file_input_stream ) ); player.set_module( Player.load_module( file_input_stream ) );
file_input_stream.close(); file_input_stream.close();
player.play(); player.play();
} }
/** /**
Decode the data in the specified InputStream into a Module instance. Decode the data in the specified InputStream into a Module instance.
@param input an InputStream containing the module file to be decoded. @param input an InputStream containing the module file to be decoded.
@throws IllegalArgumentException if the data is not recognised as a module file. @throws IllegalArgumentException if the data is not recognised as a module file.
*/ */
public static Module load_module( InputStream input ) throws IllegalArgumentException, IOException { public static Module load_module( InputStream input ) throws IllegalArgumentException, IOException {
DataInputStream data_input_stream = new DataInputStream( input ); DataInputStream data_input_stream = new DataInputStream( input );
/* Check if data is in XM format.*/ /* Check if data is in XM format.*/
byte[] xm_header = new byte[ 60 ]; byte[] xm_header = new byte[ 60 ];
data_input_stream.readFully( xm_header ); data_input_stream.readFully( xm_header );
if( FastTracker2.is_xm( xm_header ) ) if( FastTracker2.is_xm( xm_header ) )
return FastTracker2.load_xm( xm_header, data_input_stream ); return FastTracker2.load_xm( xm_header, data_input_stream );
/* Check if data is in ScreamTracker 3 format.*/ /* Check if data is in ScreamTracker 3 format.*/
byte[] s3m_header = new byte[ 96 ]; byte[] s3m_header = new byte[ 96 ];
System.arraycopy( xm_header, 0, s3m_header, 0, 60 ); System.arraycopy( xm_header, 0, s3m_header, 0, 60 );
data_input_stream.readFully( s3m_header, 60, 36 ); data_input_stream.readFully( s3m_header, 60, 36 );
if( ScreamTracker3.is_s3m( s3m_header ) ) if( ScreamTracker3.is_s3m( s3m_header ) )
return ScreamTracker3.load_s3m( s3m_header, data_input_stream ); return ScreamTracker3.load_s3m( s3m_header, data_input_stream );
/* Check if data is in ProTracker format.*/ /* Check if data is in ProTracker format.*/
byte[] mod_header = new byte[ 1084 ]; byte[] mod_header = new byte[ 1084 ];
System.arraycopy( s3m_header, 0, mod_header, 0, 96 ); System.arraycopy( s3m_header, 0, mod_header, 0, 96 );
data_input_stream.readFully( mod_header, 96, 988 ); data_input_stream.readFully( mod_header, 96, 988 );
return ProTracker.load_mod( mod_header, data_input_stream ); return ProTracker.load_mod( mod_header, data_input_stream );
} }
/** /**
Instantiate a new Player. Instantiate a new Player.
*/ */
public Player() throws LineUnavailableException { public Player() throws LineUnavailableException {
ibxm = new IBXM( 48000 ); ibxm = new IBXM( 48000 );
set_loop( true ); set_loop( true );
output_line = AudioSystem.getSourceDataLine( new AudioFormat( 48000, 16, 2, true, true ) ); output_line = AudioSystem.getSourceDataLine( new AudioFormat( 48000, 16, 2, true, true ) );
output_buffer = new byte[ 1024 * 4 ]; output_buffer = new byte[ 1024 * 4 ];
} }
/** /**
Set the Module instance to be played. Set the Module instance to be played.
*/ */
public void set_module( Module m ) { public void set_module( Module m ) {
if( m != null ) module = m; if( m != null ) module = m;
stop(); stop();
ibxm.set_module( module ); ibxm.set_module( module );
song_duration = ibxm.calculate_song_duration(); song_duration = ibxm.calculate_song_duration();
} }
/** /**
If loop is true, playback will continue indefinitely, If loop is true, playback will continue indefinitely,
otherwise the module will play through once and stop. otherwise the module will play through once and stop.
*/ */
public void set_loop( boolean loop ) { public void set_loop( boolean loop ) {
this.loop = loop; this.loop = loop;
} }
/** /**
Open the audio device and begin playback. Open the audio device and begin playback.
If a module is already playing it will be restarted. If a module is already playing it will be restarted.
*/ */
public void play() { public void play() {
stop(); stop();
play_thread = new Thread( new Driver() ); play_thread = new Thread( new Driver() );
play_thread.start(); play_thread.start();
} }
/** /**
Stop playback and close the audio device. Stop playback and close the audio device.
*/ */
public void stop() { public void stop() {
running = false; running = false;
if( play_thread != null ) { if( play_thread != null ) {
try { try {
play_thread.join(); play_thread.join();
} catch( InterruptedException ie ) {} } catch( InterruptedException ie ) {}
} }
} }
private class Driver implements Runnable { private class Driver implements Runnable {
public void run() { public void run() {
if( running ) return; if( running ) return;
try { try {
output_line.open(); output_line.open();
output_line.start(); output_line.start();
play_position = 0; play_position = 0;
running = true; running = true;
while( running ) { while( running ) {
int frames = song_duration - play_position; int frames = song_duration - play_position;
if( frames > 1024 ) frames = 1024; if( frames > 1024 ) frames = 1024;
ibxm.get_audio( output_buffer, frames ); ibxm.get_audio( output_buffer, frames );
output_line.write( output_buffer, 0, frames * 4 ); output_line.write( output_buffer, 0, frames * 4 );
play_position += frames; play_position += frames;
if( play_position >= song_duration ) { if( play_position >= song_duration ) {
play_position = 0; play_position = 0;
if( !loop ) running = false; if( !loop ) running = false;
} }
} }
output_line.drain(); output_line.drain();
output_line.close(); output_line.close();
} catch( LineUnavailableException lue ) { } catch( LineUnavailableException lue ) {
lue.printStackTrace(); lue.printStackTrace();
} }
} }
} }
} }

View File

@ -1,234 +1,234 @@
package ibxm; package ibxm;
import java.io.*; import java.io.*;
public class ProTracker { public class ProTracker {
public static boolean is_mod( byte[] header_1084_bytes ) { public static boolean is_mod( byte[] header_1084_bytes ) {
boolean is_mod; boolean is_mod;
is_mod = false; is_mod = false;
if( calculate_num_channels( header_1084_bytes ) > 0 ) { if( calculate_num_channels( header_1084_bytes ) > 0 ) {
is_mod = true; is_mod = true;
} }
return is_mod; return is_mod;
} }
public static Module load_mod( byte[] header_1084_bytes, DataInput data_input ) throws IOException { public static Module load_mod( byte[] header_1084_bytes, DataInput data_input ) throws IOException {
int num_channels, channel_idx, panning; int num_channels, channel_idx, panning;
int sequence_length, restart_idx, sequence_idx; int sequence_length, restart_idx, sequence_idx;
int num_patterns, pattern_idx, instrument_idx; int num_patterns, pattern_idx, instrument_idx;
Module module; Module module;
num_channels = calculate_num_channels( header_1084_bytes ); num_channels = calculate_num_channels( header_1084_bytes );
if( num_channels < 1 ) { if( num_channels < 1 ) {
throw new IllegalArgumentException( "ProTracker: Unrecognised module format!" ); throw new IllegalArgumentException( "ProTracker: Unrecognised module format!" );
} }
module = new Module(); module = new Module();
module.song_title = ascii_text( header_1084_bytes, 0, 20 ); module.song_title = ascii_text( header_1084_bytes, 0, 20 );
module.pal = ( num_channels == 4 ); module.pal = ( num_channels == 4 );
module.global_volume = 64; module.global_volume = 64;
module.channel_gain = IBXM.FP_ONE * 3 / 8; module.channel_gain = IBXM.FP_ONE * 3 / 8;
module.default_speed = 6; module.default_speed = 6;
module.default_tempo = 125; module.default_tempo = 125;
module.set_num_channels( num_channels ); module.set_num_channels( num_channels );
for( channel_idx = 0; channel_idx < num_channels; channel_idx++ ) { for( channel_idx = 0; channel_idx < num_channels; channel_idx++ ) {
panning = 64; panning = 64;
if( ( channel_idx & 0x03 ) == 0x01 || ( channel_idx & 0x03 ) == 0x02 ) { if( ( channel_idx & 0x03 ) == 0x01 || ( channel_idx & 0x03 ) == 0x02 ) {
panning = 192; panning = 192;
} }
module.set_initial_panning( channel_idx, panning ); module.set_initial_panning( channel_idx, panning );
} }
sequence_length = header_1084_bytes[ 950 ] & 0x7F; sequence_length = header_1084_bytes[ 950 ] & 0x7F;
restart_idx = header_1084_bytes[ 951 ] & 0x7F; restart_idx = header_1084_bytes[ 951 ] & 0x7F;
if( restart_idx >= sequence_length ) { if( restart_idx >= sequence_length ) {
restart_idx = 0; restart_idx = 0;
} }
module.restart_sequence_index = restart_idx; module.restart_sequence_index = restart_idx;
module.set_sequence_length( sequence_length ); module.set_sequence_length( sequence_length );
for( sequence_idx = 0; sequence_idx < sequence_length; sequence_idx++ ) { for( sequence_idx = 0; sequence_idx < sequence_length; sequence_idx++ ) {
module.set_sequence( sequence_idx, header_1084_bytes[ 952 + sequence_idx ] & 0x7F ); module.set_sequence( sequence_idx, header_1084_bytes[ 952 + sequence_idx ] & 0x7F );
} }
num_patterns = calculate_num_patterns( header_1084_bytes ); num_patterns = calculate_num_patterns( header_1084_bytes );
module.set_num_patterns( num_patterns ); module.set_num_patterns( num_patterns );
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
module.set_pattern( pattern_idx, read_mod_pattern( data_input, num_channels ) ); module.set_pattern( pattern_idx, read_mod_pattern( data_input, num_channels ) );
} }
module.set_num_instruments( 31 ); module.set_num_instruments( 31 );
for( instrument_idx = 1; instrument_idx <= 31; instrument_idx++ ) { for( instrument_idx = 1; instrument_idx <= 31; instrument_idx++ ) {
module.set_instrument( instrument_idx, read_mod_instrument( header_1084_bytes, instrument_idx, data_input ) ); module.set_instrument( instrument_idx, read_mod_instrument( header_1084_bytes, instrument_idx, data_input ) );
} }
return module; return module;
} }
private static int calculate_num_patterns( byte[] module_header ) { private static int calculate_num_patterns( byte[] module_header ) {
int num_patterns, order_entry, pattern_idx; int num_patterns, order_entry, pattern_idx;
num_patterns = 0; num_patterns = 0;
for( pattern_idx = 0; pattern_idx < 128; pattern_idx++ ) { for( pattern_idx = 0; pattern_idx < 128; pattern_idx++ ) {
order_entry = module_header[ 952 + pattern_idx ] & 0x7F; order_entry = module_header[ 952 + pattern_idx ] & 0x7F;
if( order_entry >= num_patterns ) { if( order_entry >= num_patterns ) {
num_patterns = order_entry + 1; num_patterns = order_entry + 1;
} }
} }
return num_patterns; return num_patterns;
} }
private static int calculate_num_channels( byte[] module_header ) { private static int calculate_num_channels( byte[] module_header ) {
int num_channels; int num_channels;
switch( ( module_header[ 1082 ] << 8 ) | module_header[ 1083 ] ) { switch( ( module_header[ 1082 ] << 8 ) | module_header[ 1083 ] ) {
case 0x4b2e: /* M.K. */ case 0x4b2e: /* M.K. */
case 0x4b21: /* M!K! */ case 0x4b21: /* M!K! */
case 0x542e: /* N.T. */ case 0x542e: /* N.T. */
case 0x5434: /* FLT4 */ case 0x5434: /* FLT4 */
num_channels = 4; num_channels = 4;
break; break;
case 0x484e: /* xCHN */ case 0x484e: /* xCHN */
num_channels = module_header[ 1080 ] - 48; num_channels = module_header[ 1080 ] - 48;
break; break;
case 0x4348: /* xxCH */ case 0x4348: /* xxCH */
num_channels = ( ( module_header[ 1080 ] - 48 ) * 10 ) + ( module_header[ 1081 ] - 48 ); num_channels = ( ( module_header[ 1080 ] - 48 ) * 10 ) + ( module_header[ 1081 ] - 48 );
break; break;
default: default:
/* Not recognised. */ /* Not recognised. */
num_channels = 0; num_channels = 0;
break; break;
} }
return num_channels; return num_channels;
} }
private static Pattern read_mod_pattern( DataInput data_input, int num_channels ) throws IOException { private static Pattern read_mod_pattern( DataInput data_input, int num_channels ) throws IOException {
int input_idx, output_idx; int input_idx, output_idx;
int period, instrument, effect, effect_param; int period, instrument, effect, effect_param;
Pattern pattern; Pattern pattern;
byte[] input_pattern_data, output_pattern_data; byte[] input_pattern_data, output_pattern_data;
pattern = new Pattern(); pattern = new Pattern();
pattern.num_rows = 64; pattern.num_rows = 64;
input_pattern_data = new byte[ 64 * num_channels * 4 ]; input_pattern_data = new byte[ 64 * num_channels * 4 ];
output_pattern_data = new byte[ 64 * num_channels * 5 ]; output_pattern_data = new byte[ 64 * num_channels * 5 ];
data_input.readFully( input_pattern_data ); data_input.readFully( input_pattern_data );
input_idx = 0; input_idx = 0;
output_idx = 0; output_idx = 0;
while( input_idx < input_pattern_data.length ) { while( input_idx < input_pattern_data.length ) {
period = ( input_pattern_data[ input_idx ] & 0x0F ) << 8; period = ( input_pattern_data[ input_idx ] & 0x0F ) << 8;
period = period | ( input_pattern_data[ input_idx + 1 ] & 0xFF ); period = period | ( input_pattern_data[ input_idx + 1 ] & 0xFF );
output_pattern_data[ output_idx ] = to_key( period ); output_pattern_data[ output_idx ] = to_key( period );
instrument = input_pattern_data[ input_idx ] & 0x10; instrument = input_pattern_data[ input_idx ] & 0x10;
instrument = instrument | ( ( input_pattern_data[ input_idx + 2 ] & 0xF0 ) >> 4 ); instrument = instrument | ( ( input_pattern_data[ input_idx + 2 ] & 0xF0 ) >> 4 );
output_pattern_data[ output_idx + 1 ] = ( byte ) instrument; output_pattern_data[ output_idx + 1 ] = ( byte ) instrument;
effect = input_pattern_data[ input_idx + 2 ] & 0x0F; effect = input_pattern_data[ input_idx + 2 ] & 0x0F;
effect_param = input_pattern_data[ input_idx + 3 ] & 0xFF; effect_param = input_pattern_data[ input_idx + 3 ] & 0xFF;
if( effect == 0x01 && effect_param == 0 ) { if( effect == 0x01 && effect_param == 0 ) {
/* Portamento up of zero has no effect. */ /* Portamento up of zero has no effect. */
effect = 0; effect = 0;
} }
if( effect == 0x02 && effect_param == 0 ) { if( effect == 0x02 && effect_param == 0 ) {
/* Portamento down of zero has no effect. */ /* Portamento down of zero has no effect. */
effect = 0; effect = 0;
} }
if( effect == 0x08 && num_channels == 4 ) { if( effect == 0x08 && num_channels == 4 ) {
/* Some Amiga mods use effect 0x08 for reasons other than panning.*/ /* Some Amiga mods use effect 0x08 for reasons other than panning.*/
effect = 0; effect = 0;
effect_param = 0; effect_param = 0;
} }
if( effect == 0x0A && effect_param == 0 ) { if( effect == 0x0A && effect_param == 0 ) {
/* Volume slide of zero has no effect.*/ /* Volume slide of zero has no effect.*/
effect = 0; effect = 0;
} }
if( effect == 0x05 && effect_param == 0 ) { if( effect == 0x05 && effect_param == 0 ) {
/* Porta + Volume slide of zero has no effect.*/ /* Porta + Volume slide of zero has no effect.*/
effect = 0x03; effect = 0x03;
} }
if( effect == 0x06 && effect_param == 0 ) { if( effect == 0x06 && effect_param == 0 ) {
/* Vibrato + Volume slide of zero has no effect.*/ /* Vibrato + Volume slide of zero has no effect.*/
effect = 0x04; effect = 0x04;
} }
output_pattern_data[ output_idx + 3 ] = ( byte ) effect; output_pattern_data[ output_idx + 3 ] = ( byte ) effect;
output_pattern_data[ output_idx + 4 ] = ( byte ) effect_param; output_pattern_data[ output_idx + 4 ] = ( byte ) effect_param;
input_idx += 4; input_idx += 4;
output_idx += 5; output_idx += 5;
} }
pattern.set_pattern_data( output_pattern_data ); pattern.set_pattern_data( output_pattern_data );
return pattern; return pattern;
} }
private static Instrument read_mod_instrument( byte[] mod_header, int idx, DataInput data_input ) throws IOException { private static Instrument read_mod_instrument( byte[] mod_header, int idx, DataInput data_input ) throws IOException {
int header_offset, sample_data_length; int header_offset, sample_data_length;
int loop_start, loop_length, sample_idx, fine_tune; int loop_start, loop_length, sample_idx, fine_tune;
Instrument instrument; Instrument instrument;
Sample sample; Sample sample;
byte[] raw_sample_data; byte[] raw_sample_data;
short[] sample_data; short[] sample_data;
header_offset = ( idx - 1 ) * 30 + 20; header_offset = ( idx - 1 ) * 30 + 20;
instrument = new Instrument(); instrument = new Instrument();
instrument.name = ascii_text( mod_header, header_offset, 22 ); instrument.name = ascii_text( mod_header, header_offset, 22 );
sample = new Sample(); sample = new Sample();
sample_data_length = unsigned_short_be( mod_header, header_offset + 22 ) << 1; sample_data_length = unsigned_short_be( mod_header, header_offset + 22 ) << 1;
fine_tune = mod_header[ header_offset + 24 ] & 0x0F; fine_tune = mod_header[ header_offset + 24 ] & 0x0F;
if( fine_tune > 7 ) { if( fine_tune > 7 ) {
fine_tune -= 16; fine_tune -= 16;
} }
sample.transpose = ( fine_tune << IBXM.FP_SHIFT ) / 96; sample.transpose = ( fine_tune << IBXM.FP_SHIFT ) / 96;
sample.volume = mod_header[ header_offset + 25 ] & 0x7F; sample.volume = mod_header[ header_offset + 25 ] & 0x7F;
loop_start = unsigned_short_be( mod_header, header_offset + 26 ) << 1; loop_start = unsigned_short_be( mod_header, header_offset + 26 ) << 1;
loop_length = unsigned_short_be( mod_header, header_offset + 28 ) << 1; loop_length = unsigned_short_be( mod_header, header_offset + 28 ) << 1;
if( loop_length < 4 ) { if( loop_length < 4 ) {
loop_length = 0; loop_length = 0;
} }
raw_sample_data = new byte[ sample_data_length ]; raw_sample_data = new byte[ sample_data_length ];
sample_data = new short[ sample_data_length ]; sample_data = new short[ sample_data_length ];
try { try {
data_input.readFully( raw_sample_data ); data_input.readFully( raw_sample_data );
} catch( EOFException e ) { } catch( EOFException e ) {
System.out.println( "ProTracker: Instrument " + idx + " has samples missing." ); System.out.println( "ProTracker: Instrument " + idx + " has samples missing." );
} }
for( sample_idx = 0; sample_idx < raw_sample_data.length; sample_idx++ ) { for( sample_idx = 0; sample_idx < raw_sample_data.length; sample_idx++ ) {
sample_data[ sample_idx ] = ( short ) ( raw_sample_data[ sample_idx ] << 8 ); sample_data[ sample_idx ] = ( short ) ( raw_sample_data[ sample_idx ] << 8 );
} }
sample.set_sample_data( sample_data, loop_start, loop_length, false ); sample.set_sample_data( sample_data, loop_start, loop_length, false );
instrument.set_num_samples( 1 ); instrument.set_num_samples( 1 );
instrument.set_sample( 0, sample ); instrument.set_sample( 0, sample );
return instrument; return instrument;
} }
private static byte to_key( int period ) { private static byte to_key( int period ) {
int oct, key; int oct, key;
if( period < 32 ) { if( period < 32 ) {
key = 0; key = 0;
} else { } else {
oct = LogTable.log_2( 7256 ) - LogTable.log_2( period ); oct = LogTable.log_2( 7256 ) - LogTable.log_2( period );
if( oct < 0 ) { if( oct < 0 ) {
key = 0; key = 0;
} else { } else {
key = oct * 12; key = oct * 12;
key = key >> ( IBXM.FP_SHIFT - 1 ); key = key >> ( IBXM.FP_SHIFT - 1 );
key = ( key >> 1 ) + ( key & 1 ); key = ( key >> 1 ) + ( key & 1 );
} }
} }
return ( byte ) key; return ( byte ) key;
} }
private static int unsigned_short_be( byte[] buf, int offset ) { private static int unsigned_short_be( byte[] buf, int offset ) {
int value; int value;
value = ( buf[ offset ] & 0xFF ) << 8; value = ( buf[ offset ] & 0xFF ) << 8;
value = value | ( buf[ offset + 1 ] & 0xFF ); value = value | ( buf[ offset + 1 ] & 0xFF );
return value; return value;
} }
private static String ascii_text( byte[] buffer, int offset, int length ) { private static String ascii_text( byte[] buffer, int offset, int length ) {
int idx, chr; int idx, chr;
byte[] string_buffer; byte[] string_buffer;
String string; String string;
string_buffer = new byte[ length ]; string_buffer = new byte[ length ];
for( idx = 0; idx < length; idx++ ) { for( idx = 0; idx < length; idx++ ) {
chr = buffer[ offset + idx ]; chr = buffer[ offset + idx ];
if( chr < 32 ) { if( chr < 32 ) {
chr = 32; chr = 32;
} }
string_buffer[ idx ] = ( byte ) chr; string_buffer[ idx ] = ( byte ) chr;
} }
try { try {
string = new String( string_buffer, 0, length, "ISO-8859-1" ); string = new String( string_buffer, 0, length, "ISO-8859-1" );
} catch( UnsupportedEncodingException e ) { } catch( UnsupportedEncodingException e ) {
string = ""; string = "";
} }
return string; return string;
} }
} }

View File

@ -1,239 +1,239 @@
package ibxm; package ibxm;
public class Sample { public class Sample {
public String name; public String name;
public boolean set_panning; public boolean set_panning;
public int volume, panning; public int volume, panning;
public int transpose; public int transpose;
private int loop_start, loop_length; private int loop_start, loop_length;
private short[] sample_data; private short[] sample_data;
/* For the sinc interpolator.*/ /* For the sinc interpolator.*/
private static final int POINT_SHIFT = 4; private static final int POINT_SHIFT = 4;
private static final int POINTS = 1 << POINT_SHIFT; private static final int POINTS = 1 << POINT_SHIFT;
private static final int OVERLAP = POINTS >> 1; private static final int OVERLAP = POINTS >> 1;
private static final int INTERP_SHIFT = IBXM.FP_SHIFT - 4; private static final int INTERP_SHIFT = IBXM.FP_SHIFT - 4;
private static final int INTERP_BITMASK = ( 1 << INTERP_SHIFT ) - 1; private static final int INTERP_BITMASK = ( 1 << INTERP_SHIFT ) - 1;
private static final short[] sinc_table = { private static final short[] sinc_table = {
0, -7, 27, -71, 142, -227, 299, 32439, 299, -227, 142, -71, 27, -7, 0, 0, 0, -7, 27, -71, 142, -227, 299, 32439, 299, -227, 142, -71, 27, -7, 0, 0,
0, 0, -5, 36, -142, 450, -1439, 32224, 2302, -974, 455, -190, 64, -15, 2, 0, 0, 0, -5, 36, -142, 450, -1439, 32224, 2302, -974, 455, -190, 64, -15, 2, 0,
0, 6, -33, 128, -391, 1042, -2894, 31584, 4540, -1765, 786, -318, 105, -25, 3, 0, 0, 6, -33, 128, -391, 1042, -2894, 31584, 4540, -1765, 786, -318, 105, -25, 3, 0,
0, 10, -55, 204, -597, 1533, -4056, 30535, 6977, -2573, 1121, -449, 148, -36, 5, 0, 0, 10, -55, 204, -597, 1533, -4056, 30535, 6977, -2573, 1121, -449, 148, -36, 5, 0,
-1, 13, -71, 261, -757, 1916, -4922, 29105, 9568, -3366, 1448, -578, 191, -47, 7, 0, -1, 13, -71, 261, -757, 1916, -4922, 29105, 9568, -3366, 1448, -578, 191, -47, 7, 0,
-1, 15, -81, 300, -870, 2185, -5498, 27328, 12263, -4109, 1749, -698, 232, -58, 9, 0, -1, 15, -81, 300, -870, 2185, -5498, 27328, 12263, -4109, 1749, -698, 232, -58, 9, 0,
-1, 15, -86, 322, -936, 2343, -5800, 25249, 15006, -4765, 2011, -802, 269, -68, 10, 0, -1, 15, -86, 322, -936, 2343, -5800, 25249, 15006, -4765, 2011, -802, 269, -68, 10, 0,
-1, 15, -87, 328, -957, 2394, -5849, 22920, 17738, -5298, 2215, -885, 299, -77, 12, 0, -1, 15, -87, 328, -957, 2394, -5849, 22920, 17738, -5298, 2215, -885, 299, -77, 12, 0,
0, 14, -83, 319, -938, 2347, -5671, 20396, 20396, -5671, 2347, -938, 319, -83, 14, 0, 0, 14, -83, 319, -938, 2347, -5671, 20396, 20396, -5671, 2347, -938, 319, -83, 14, 0,
0, 12, -77, 299, -885, 2215, -5298, 17738, 22920, -5849, 2394, -957, 328, -87, 15, -1, 0, 12, -77, 299, -885, 2215, -5298, 17738, 22920, -5849, 2394, -957, 328, -87, 15, -1,
0, 10, -68, 269, -802, 2011, -4765, 15006, 25249, -5800, 2343, -936, 322, -86, 15, -1, 0, 10, -68, 269, -802, 2011, -4765, 15006, 25249, -5800, 2343, -936, 322, -86, 15, -1,
0, 9, -58, 232, -698, 1749, -4109, 12263, 27328, -5498, 2185, -870, 300, -81, 15, -1, 0, 9, -58, 232, -698, 1749, -4109, 12263, 27328, -5498, 2185, -870, 300, -81, 15, -1,
0, 7, -47, 191, -578, 1448, -3366, 9568, 29105, -4922, 1916, -757, 261, -71, 13, -1, 0, 7, -47, 191, -578, 1448, -3366, 9568, 29105, -4922, 1916, -757, 261, -71, 13, -1,
0, 5, -36, 148, -449, 1121, -2573, 6977, 30535, -4056, 1533, -597, 204, -55, 10, 0, 0, 5, -36, 148, -449, 1121, -2573, 6977, 30535, -4056, 1533, -597, 204, -55, 10, 0,
0, 3, -25, 105, -318, 786, -1765, 4540, 31584, -2894, 1042, -391, 128, -33, 6, 0, 0, 3, -25, 105, -318, 786, -1765, 4540, 31584, -2894, 1042, -391, 128, -33, 6, 0,
0, 2, -15, 64, -190, 455, -974, 2302, 32224, -1439, 450, -142, 36, -5, 0, 0, 0, 2, -15, 64, -190, 455, -974, 2302, 32224, -1439, 450, -142, 36, -5, 0, 0,
0, 0, -7, 27, -71, 142, -227, 299, 32439, 299, -227, 142, -71, 27, -7, 0 0, 0, -7, 27, -71, 142, -227, 299, 32439, 299, -227, 142, -71, 27, -7, 0
}; };
public Sample() { public Sample() {
name = ""; name = "";
set_sample_data( new short[ 0 ], 0, 0, false ); set_sample_data( new short[ 0 ], 0, 0, false );
} }
public void set_sample_data( short[] data, int loop_start, int loop_length, boolean ping_pong ) { public void set_sample_data( short[] data, int loop_start, int loop_length, boolean ping_pong ) {
int offset; int offset;
short sample; short sample;
if( loop_start < 0 ) { if( loop_start < 0 ) {
loop_start = 0; loop_start = 0;
} }
if( loop_start >= data.length ) { if( loop_start >= data.length ) {
loop_start = data.length - 1; loop_start = data.length - 1;
} }
if( loop_start + loop_length > data.length ) { if( loop_start + loop_length > data.length ) {
loop_length = data.length - loop_start; loop_length = data.length - loop_start;
} }
if( loop_length <= 1 ) { if( loop_length <= 1 ) {
sample_data = new short[ OVERLAP + data.length + OVERLAP * 3 ]; sample_data = new short[ OVERLAP + data.length + OVERLAP * 3 ];
System.arraycopy( data, 0, sample_data, OVERLAP, data.length ); System.arraycopy( data, 0, sample_data, OVERLAP, data.length );
offset = 0; offset = 0;
while( offset < OVERLAP ) { while( offset < OVERLAP ) {
sample = sample_data[ OVERLAP + data.length - 1 ]; sample = sample_data[ OVERLAP + data.length - 1 ];
sample = ( short ) ( sample * ( OVERLAP - offset ) / OVERLAP ); sample = ( short ) ( sample * ( OVERLAP - offset ) / OVERLAP );
sample_data[ OVERLAP + data.length + offset ] = sample; sample_data[ OVERLAP + data.length + offset ] = sample;
offset += 1; offset += 1;
} }
loop_start = OVERLAP + data.length + OVERLAP; loop_start = OVERLAP + data.length + OVERLAP;
loop_length = 1; loop_length = 1;
} else { } else {
if( ping_pong ) { if( ping_pong ) {
sample_data = new short[ OVERLAP + loop_start + loop_length * 2 + OVERLAP * 2 ]; sample_data = new short[ OVERLAP + loop_start + loop_length * 2 + OVERLAP * 2 ];
System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length ); System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length );
offset = 0; offset = 0;
while( offset < loop_length ) { while( offset < loop_length ) {
sample = data[ loop_start + loop_length - offset - 1 ]; sample = data[ loop_start + loop_length - offset - 1 ];
sample_data[ OVERLAP + loop_start + loop_length + offset ] = sample; sample_data[ OVERLAP + loop_start + loop_length + offset ] = sample;
offset += 1; offset += 1;
} }
loop_start = loop_start + OVERLAP; loop_start = loop_start + OVERLAP;
loop_length = loop_length * 2; loop_length = loop_length * 2;
} else { } else {
sample_data = new short[ OVERLAP + loop_start + loop_length + OVERLAP * 2 ]; sample_data = new short[ OVERLAP + loop_start + loop_length + OVERLAP * 2 ];
System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length ); System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length );
loop_start = loop_start + OVERLAP; loop_start = loop_start + OVERLAP;
} }
offset = 0; offset = 0;
while( offset < OVERLAP * 2 ) { while( offset < OVERLAP * 2 ) {
sample = sample_data[ loop_start + offset ]; sample = sample_data[ loop_start + offset ];
sample_data[ loop_start + loop_length + offset ] = sample; sample_data[ loop_start + loop_length + offset ] = sample;
offset += 1; offset += 1;
} }
} }
this.loop_start = loop_start; this.loop_start = loop_start;
this.loop_length = loop_length; this.loop_length = loop_length;
} }
public void resample_nearest( public void resample_nearest(
int sample_idx, int sample_frac, int step, int left_gain, int right_gain, int sample_idx, int sample_frac, int step, int left_gain, int right_gain,
int[] mix_buffer, int frame_offset, int frames ) { int[] mix_buffer, int frame_offset, int frames ) {
int loop_end, offset, end, max_sample_idx; int loop_end, offset, end, max_sample_idx;
sample_idx += OVERLAP; sample_idx += OVERLAP;
loop_end = loop_start + loop_length - 1; loop_end = loop_start + loop_length - 1;
offset = frame_offset << 1; offset = frame_offset << 1;
end = ( frame_offset + frames - 1 ) << 1; end = ( frame_offset + frames - 1 ) << 1;
while( frames > 0 ) { while( frames > 0 ) {
if( sample_idx > loop_end ) { if( sample_idx > loop_end ) {
if( loop_length <= 1 ) { if( loop_length <= 1 ) {
break; break;
} }
sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length; sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length;
} }
max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT ); max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT );
if( max_sample_idx > loop_end ) { if( max_sample_idx > loop_end ) {
while( sample_idx <= loop_end ) { while( sample_idx <= loop_end ) {
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * left_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += sample_data[ sample_idx ] * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * right_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += sample_data[ sample_idx ] * right_gain >> IBXM.FP_SHIFT;
sample_frac += step; sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT; sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK; sample_frac &= IBXM.FP_MASK;
} }
} else { } else {
while( offset <= end ) { while( offset <= end ) {
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * left_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += sample_data[ sample_idx ] * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += sample_data[ sample_idx ] * right_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += sample_data[ sample_idx ] * right_gain >> IBXM.FP_SHIFT;
sample_frac += step; sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT; sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK; sample_frac &= IBXM.FP_MASK;
} }
} }
frames = ( end - offset + 2 ) >> 1; frames = ( end - offset + 2 ) >> 1;
} }
} }
public void resample_linear( public void resample_linear(
int sample_idx, int sample_frac, int step, int left_gain, int right_gain, int sample_idx, int sample_frac, int step, int left_gain, int right_gain,
int[] mix_buffer, int frame_offset, int frames ) { int[] mix_buffer, int frame_offset, int frames ) {
int loop_end, offset, end, max_sample_idx, amplitude; int loop_end, offset, end, max_sample_idx, amplitude;
sample_idx += OVERLAP; sample_idx += OVERLAP;
loop_end = loop_start + loop_length - 1; loop_end = loop_start + loop_length - 1;
offset = frame_offset << 1; offset = frame_offset << 1;
end = ( frame_offset + frames - 1 ) << 1; end = ( frame_offset + frames - 1 ) << 1;
while( frames > 0 ) { while( frames > 0 ) {
if( sample_idx > loop_end ) { if( sample_idx > loop_end ) {
if( loop_length <= 1 ) { if( loop_length <= 1 ) {
break; break;
} }
sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length; sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length;
} }
max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT ); max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT );
if( max_sample_idx > loop_end ) { if( max_sample_idx > loop_end ) {
while( sample_idx <= loop_end ) { while( sample_idx <= loop_end ) {
amplitude = sample_data[ sample_idx ]; amplitude = sample_data[ sample_idx ];
amplitude += ( sample_data[ sample_idx + 1 ] - amplitude ) * sample_frac >> IBXM.FP_SHIFT; amplitude += ( sample_data[ sample_idx + 1 ] - amplitude ) * sample_frac >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * left_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += amplitude * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * right_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += amplitude * right_gain >> IBXM.FP_SHIFT;
sample_frac += step; sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT; sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK; sample_frac &= IBXM.FP_MASK;
} }
} else { } else {
while( offset <= end ) { while( offset <= end ) {
amplitude = sample_data[ sample_idx ]; amplitude = sample_data[ sample_idx ];
amplitude += ( sample_data[ sample_idx + 1 ] - amplitude ) * sample_frac >> IBXM.FP_SHIFT; amplitude += ( sample_data[ sample_idx + 1 ] - amplitude ) * sample_frac >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * left_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += amplitude * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset++ ] += amplitude * right_gain >> IBXM.FP_SHIFT; mix_buffer[ offset++ ] += amplitude * right_gain >> IBXM.FP_SHIFT;
sample_frac += step; sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT; sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK; sample_frac &= IBXM.FP_MASK;
} }
} }
frames = ( end - offset + 2 ) >> 1; frames = ( end - offset + 2 ) >> 1;
} }
} }
public void resample_sinc( public void resample_sinc(
int sample_idx, int sample_frac, int step, int left_gain, int right_gain, int sample_idx, int sample_frac, int step, int left_gain, int right_gain,
int[] mix_buffer, int frame_offset, int frames ) { int[] mix_buffer, int frame_offset, int frames ) {
int offset, end, loop_end, table_idx, a1, a2, amplitude; int offset, end, loop_end, table_idx, a1, a2, amplitude;
loop_end = loop_start + loop_length - 1; loop_end = loop_start + loop_length - 1;
offset = frame_offset << 1; offset = frame_offset << 1;
end = ( frame_offset + frames - 1 ) << 1; end = ( frame_offset + frames - 1 ) << 1;
while( offset <= end ) { while( offset <= end ) {
if( sample_idx > loop_end ) { if( sample_idx > loop_end ) {
if( loop_length <= 1 ) { if( loop_length <= 1 ) {
break; break;
} }
sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length; sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length;
} }
table_idx = ( sample_frac >> INTERP_SHIFT ) << POINT_SHIFT; table_idx = ( sample_frac >> INTERP_SHIFT ) << POINT_SHIFT;
a1 = sinc_table[ table_idx + 0 ] * sample_data[ sample_idx + 0 ] >> 15; a1 = sinc_table[ table_idx + 0 ] * sample_data[ sample_idx + 0 ] >> 15;
a1 += sinc_table[ table_idx + 1 ] * sample_data[ sample_idx + 1 ] >> 15; a1 += sinc_table[ table_idx + 1 ] * sample_data[ sample_idx + 1 ] >> 15;
a1 += sinc_table[ table_idx + 2 ] * sample_data[ sample_idx + 2 ] >> 15; a1 += sinc_table[ table_idx + 2 ] * sample_data[ sample_idx + 2 ] >> 15;
a1 += sinc_table[ table_idx + 3 ] * sample_data[ sample_idx + 3 ] >> 15; a1 += sinc_table[ table_idx + 3 ] * sample_data[ sample_idx + 3 ] >> 15;
a1 += sinc_table[ table_idx + 4 ] * sample_data[ sample_idx + 4 ] >> 15; a1 += sinc_table[ table_idx + 4 ] * sample_data[ sample_idx + 4 ] >> 15;
a1 += sinc_table[ table_idx + 5 ] * sample_data[ sample_idx + 5 ] >> 15; a1 += sinc_table[ table_idx + 5 ] * sample_data[ sample_idx + 5 ] >> 15;
a1 += sinc_table[ table_idx + 6 ] * sample_data[ sample_idx + 6 ] >> 15; a1 += sinc_table[ table_idx + 6 ] * sample_data[ sample_idx + 6 ] >> 15;
a1 += sinc_table[ table_idx + 7 ] * sample_data[ sample_idx + 7 ] >> 15; a1 += sinc_table[ table_idx + 7 ] * sample_data[ sample_idx + 7 ] >> 15;
a1 += sinc_table[ table_idx + 8 ] * sample_data[ sample_idx + 8 ] >> 15; a1 += sinc_table[ table_idx + 8 ] * sample_data[ sample_idx + 8 ] >> 15;
a1 += sinc_table[ table_idx + 9 ] * sample_data[ sample_idx + 9 ] >> 15; a1 += sinc_table[ table_idx + 9 ] * sample_data[ sample_idx + 9 ] >> 15;
a1 += sinc_table[ table_idx + 10 ] * sample_data[ sample_idx + 10 ] >> 15; a1 += sinc_table[ table_idx + 10 ] * sample_data[ sample_idx + 10 ] >> 15;
a1 += sinc_table[ table_idx + 11 ] * sample_data[ sample_idx + 11 ] >> 15; a1 += sinc_table[ table_idx + 11 ] * sample_data[ sample_idx + 11 ] >> 15;
a1 += sinc_table[ table_idx + 12 ] * sample_data[ sample_idx + 12 ] >> 15; a1 += sinc_table[ table_idx + 12 ] * sample_data[ sample_idx + 12 ] >> 15;
a1 += sinc_table[ table_idx + 13 ] * sample_data[ sample_idx + 13 ] >> 15; a1 += sinc_table[ table_idx + 13 ] * sample_data[ sample_idx + 13 ] >> 15;
a1 += sinc_table[ table_idx + 14 ] * sample_data[ sample_idx + 14 ] >> 15; a1 += sinc_table[ table_idx + 14 ] * sample_data[ sample_idx + 14 ] >> 15;
a1 += sinc_table[ table_idx + 15 ] * sample_data[ sample_idx + 15 ] >> 15; a1 += sinc_table[ table_idx + 15 ] * sample_data[ sample_idx + 15 ] >> 15;
a2 = sinc_table[ table_idx + 16 ] * sample_data[ sample_idx + 0 ] >> 15; a2 = sinc_table[ table_idx + 16 ] * sample_data[ sample_idx + 0 ] >> 15;
a2 += sinc_table[ table_idx + 17 ] * sample_data[ sample_idx + 1 ] >> 15; a2 += sinc_table[ table_idx + 17 ] * sample_data[ sample_idx + 1 ] >> 15;
a2 += sinc_table[ table_idx + 18 ] * sample_data[ sample_idx + 2 ] >> 15; a2 += sinc_table[ table_idx + 18 ] * sample_data[ sample_idx + 2 ] >> 15;
a2 += sinc_table[ table_idx + 19 ] * sample_data[ sample_idx + 3 ] >> 15; a2 += sinc_table[ table_idx + 19 ] * sample_data[ sample_idx + 3 ] >> 15;
a2 += sinc_table[ table_idx + 20 ] * sample_data[ sample_idx + 4 ] >> 15; a2 += sinc_table[ table_idx + 20 ] * sample_data[ sample_idx + 4 ] >> 15;
a2 += sinc_table[ table_idx + 21 ] * sample_data[ sample_idx + 5 ] >> 15; a2 += sinc_table[ table_idx + 21 ] * sample_data[ sample_idx + 5 ] >> 15;
a2 += sinc_table[ table_idx + 22 ] * sample_data[ sample_idx + 6 ] >> 15; a2 += sinc_table[ table_idx + 22 ] * sample_data[ sample_idx + 6 ] >> 15;
a2 += sinc_table[ table_idx + 23 ] * sample_data[ sample_idx + 7 ] >> 15; a2 += sinc_table[ table_idx + 23 ] * sample_data[ sample_idx + 7 ] >> 15;
a2 += sinc_table[ table_idx + 24 ] * sample_data[ sample_idx + 8 ] >> 15; a2 += sinc_table[ table_idx + 24 ] * sample_data[ sample_idx + 8 ] >> 15;
a2 += sinc_table[ table_idx + 25 ] * sample_data[ sample_idx + 9 ] >> 15; a2 += sinc_table[ table_idx + 25 ] * sample_data[ sample_idx + 9 ] >> 15;
a2 += sinc_table[ table_idx + 26 ] * sample_data[ sample_idx + 10 ] >> 15; a2 += sinc_table[ table_idx + 26 ] * sample_data[ sample_idx + 10 ] >> 15;
a2 += sinc_table[ table_idx + 27 ] * sample_data[ sample_idx + 11 ] >> 15; a2 += sinc_table[ table_idx + 27 ] * sample_data[ sample_idx + 11 ] >> 15;
a2 += sinc_table[ table_idx + 28 ] * sample_data[ sample_idx + 12 ] >> 15; a2 += sinc_table[ table_idx + 28 ] * sample_data[ sample_idx + 12 ] >> 15;
a2 += sinc_table[ table_idx + 29 ] * sample_data[ sample_idx + 13 ] >> 15; a2 += sinc_table[ table_idx + 29 ] * sample_data[ sample_idx + 13 ] >> 15;
a2 += sinc_table[ table_idx + 30 ] * sample_data[ sample_idx + 14 ] >> 15; a2 += sinc_table[ table_idx + 30 ] * sample_data[ sample_idx + 14 ] >> 15;
a2 += sinc_table[ table_idx + 31 ] * sample_data[ sample_idx + 15 ] >> 15; a2 += sinc_table[ table_idx + 31 ] * sample_data[ sample_idx + 15 ] >> 15;
amplitude = a1 + ( ( a2 - a1 ) * ( sample_frac & INTERP_BITMASK ) >> INTERP_SHIFT ); amplitude = a1 + ( ( a2 - a1 ) * ( sample_frac & INTERP_BITMASK ) >> INTERP_SHIFT );
mix_buffer[ offset ] += amplitude * left_gain >> IBXM.FP_SHIFT; mix_buffer[ offset ] += amplitude * left_gain >> IBXM.FP_SHIFT;
mix_buffer[ offset + 1 ] += amplitude * right_gain >> IBXM.FP_SHIFT; mix_buffer[ offset + 1 ] += amplitude * right_gain >> IBXM.FP_SHIFT;
offset += 2; offset += 2;
sample_frac += step; sample_frac += step;
sample_idx += sample_frac >> IBXM.FP_SHIFT; sample_idx += sample_frac >> IBXM.FP_SHIFT;
sample_frac &= IBXM.FP_MASK; sample_frac &= IBXM.FP_MASK;
} }
} }
public boolean has_finished( int sample_idx ) { public boolean has_finished( int sample_idx ) {
boolean finished; boolean finished;
finished = false; finished = false;
if( loop_length <= 1 && sample_idx > loop_start ) { if( loop_length <= 1 && sample_idx > loop_start ) {
finished = true; finished = true;
} }
return finished; return finished;
} }
} }

View File

@ -1,489 +1,489 @@
package ibxm; package ibxm;
import java.io.*; import java.io.*;
public class ScreamTracker3 { public class ScreamTracker3 {
private static final int[] effect_map = new int[] { private static final int[] effect_map = new int[] {
0xFF, 0xFF,
0x25, /* A: Set Speed.*/ 0x25, /* A: Set Speed.*/
0x0B, /* B: Pattern Jump.*/ 0x0B, /* B: Pattern Jump.*/
0x0D, /* C: Pattern Break.*/ 0x0D, /* C: Pattern Break.*/
0x0A, /* D: Volume Slide.*/ 0x0A, /* D: Volume Slide.*/
0x02, /* E: Portamento Down.*/ 0x02, /* E: Portamento Down.*/
0x01, /* F: Portamento Up.*/ 0x01, /* F: Portamento Up.*/
0x03, /* G: Tone Portamento.*/ 0x03, /* G: Tone Portamento.*/
0x04, /* H: Vibrato.*/ 0x04, /* H: Vibrato.*/
0x1D, /* I: Tremor.*/ 0x1D, /* I: Tremor.*/
0x00, /* J: Arpeggio.*/ 0x00, /* J: Arpeggio.*/
0x06, /* K: Vibrato + Volume Slide.*/ 0x06, /* K: Vibrato + Volume Slide.*/
0x05, /* L: Tone Portamento + Volume Slide.*/ 0x05, /* L: Tone Portamento + Volume Slide.*/
0xFF, /* M: */ 0xFF, /* M: */
0xFF, /* N: */ 0xFF, /* N: */
0x09, /* O: Sample Offset.*/ 0x09, /* O: Sample Offset.*/
0xFF, /* P: */ 0xFF, /* P: */
0x1B, /* Q: Retrig + Volume Slide.*/ 0x1B, /* Q: Retrig + Volume Slide.*/
0x07, /* R: Tremolo.*/ 0x07, /* R: Tremolo.*/
0x0E, /* S: Extended Effects.*/ 0x0E, /* S: Extended Effects.*/
0x0F, /* T: Set Tempo.*/ 0x0F, /* T: Set Tempo.*/
0x24, /* U: Fine Vibrato.*/ 0x24, /* U: Fine Vibrato.*/
0x10, /* V: Set Global Volume. */ 0x10, /* V: Set Global Volume. */
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF 0xFF, 0xFF, 0xFF, 0xFF
}; };
private static final int[] effect_s_map = new int[] { private static final int[] effect_s_map = new int[] {
0x00, /* 0: Set Filter.*/ 0x00, /* 0: Set Filter.*/
0x03, /* 1: Glissando.*/ 0x03, /* 1: Glissando.*/
0x05, /* 2: Set Fine Tune.*/ 0x05, /* 2: Set Fine Tune.*/
0x04, /* 3: Set Vibrato Waveform.*/ 0x04, /* 3: Set Vibrato Waveform.*/
0x07, /* 4: Set Tremolo Waveform.*/ 0x07, /* 4: Set Tremolo Waveform.*/
0xFF, /* 5: */ 0xFF, /* 5: */
0xFF, /* 6: */ 0xFF, /* 6: */
0xFF, /* 7: */ 0xFF, /* 7: */
0x08, /* 8: Set Panning.*/ 0x08, /* 8: Set Panning.*/
0xFF, /* 9: */ 0xFF, /* 9: */
0x09, /* A: Stereo Control.*/ 0x09, /* A: Stereo Control.*/
0x06, /* B: Pattern Loop.*/ 0x06, /* B: Pattern Loop.*/
0x0C, /* C: Note Cut.*/ 0x0C, /* C: Note Cut.*/
0x0D, /* D: Note Delay.*/ 0x0D, /* D: Note Delay.*/
0x0E, /* E: Pattern Delay.*/ 0x0E, /* E: Pattern Delay.*/
0x0F /* F: Invert Loop.*/ 0x0F /* F: Invert Loop.*/
}; };
public static boolean is_s3m( byte[] header_96_bytes ) { public static boolean is_s3m( byte[] header_96_bytes ) {
String s3m_identifier; String s3m_identifier;
s3m_identifier = ascii_text( header_96_bytes, 44, 4 ); s3m_identifier = ascii_text( header_96_bytes, 44, 4 );
return s3m_identifier.equals( "SCRM" ); return s3m_identifier.equals( "SCRM" );
} }
public static Module load_s3m( byte[] header_96_bytes, DataInput data_input ) throws IOException { public static Module load_s3m( byte[] header_96_bytes, DataInput data_input ) throws IOException {
int num_pattern_orders, num_instruments, num_patterns, num_channels; int num_pattern_orders, num_instruments, num_patterns, num_channels;
int flags, tracker_version, master_volume, panning, channel_config, sequence_length; int flags, tracker_version, master_volume, panning, channel_config, sequence_length;
int instrument_idx, pattern_idx, channel_idx, order_idx, panning_offset; int instrument_idx, pattern_idx, channel_idx, order_idx, panning_offset;
boolean signed_samples, stereo_mode, default_panning; boolean signed_samples, stereo_mode, default_panning;
int[] channel_map, sequence; int[] channel_map, sequence;
byte[] s3m_file; byte[] s3m_file;
Module module; Module module;
Instrument instrument; Instrument instrument;
s3m_file = read_s3m_file( header_96_bytes, data_input ); s3m_file = read_s3m_file( header_96_bytes, data_input );
module = new Module(); module = new Module();
module.song_title = ascii_text( s3m_file, 0, 28 ); module.song_title = ascii_text( s3m_file, 0, 28 );
num_pattern_orders = get_num_pattern_orders( s3m_file ); num_pattern_orders = get_num_pattern_orders( s3m_file );
num_instruments = get_num_instruments( s3m_file ); num_instruments = get_num_instruments( s3m_file );
num_patterns = get_num_patterns( s3m_file ); num_patterns = get_num_patterns( s3m_file );
flags = unsigned_short_le( s3m_file, 38 ); flags = unsigned_short_le( s3m_file, 38 );
tracker_version = unsigned_short_le( s3m_file, 40 ); tracker_version = unsigned_short_le( s3m_file, 40 );
if( ( flags & 0x40 ) == 0x40 || tracker_version == 0x1300 ) { if( ( flags & 0x40 ) == 0x40 || tracker_version == 0x1300 ) {
module.fast_volume_slides = true; module.fast_volume_slides = true;
} }
signed_samples = false; signed_samples = false;
if( unsigned_short_le( s3m_file, 42 ) == 0x01 ) { if( unsigned_short_le( s3m_file, 42 ) == 0x01 ) {
signed_samples = true; signed_samples = true;
} }
module.global_volume = s3m_file[ 48 ] & 0xFF; module.global_volume = s3m_file[ 48 ] & 0xFF;
module.default_speed = s3m_file[ 49 ] & 0xFF; module.default_speed = s3m_file[ 49 ] & 0xFF;
module.default_tempo = s3m_file[ 50 ] & 0xFF; module.default_tempo = s3m_file[ 50 ] & 0xFF;
master_volume = s3m_file[ 51 ] & 0x7F; master_volume = s3m_file[ 51 ] & 0x7F;
module.channel_gain = ( master_volume << IBXM.FP_SHIFT ) >> 7; module.channel_gain = ( master_volume << IBXM.FP_SHIFT ) >> 7;
stereo_mode = ( s3m_file[ 51 ] & 0x80 ) == 0x80; stereo_mode = ( s3m_file[ 51 ] & 0x80 ) == 0x80;
default_panning = ( s3m_file[ 53 ] & 0xFF ) == 0xFC; default_panning = ( s3m_file[ 53 ] & 0xFF ) == 0xFC;
channel_map = new int[ 32 ]; channel_map = new int[ 32 ];
num_channels = 0; num_channels = 0;
for( channel_idx = 0; channel_idx < 32; channel_idx++ ) { for( channel_idx = 0; channel_idx < 32; channel_idx++ ) {
channel_config = s3m_file[ 64 + channel_idx ] & 0xFF; channel_config = s3m_file[ 64 + channel_idx ] & 0xFF;
channel_map[ channel_idx ] = -1; channel_map[ channel_idx ] = -1;
if( channel_config < 16 ) { if( channel_config < 16 ) {
channel_map[ channel_idx ] = num_channels; channel_map[ channel_idx ] = num_channels;
num_channels += 1; num_channels += 1;
} }
} }
module.set_num_channels( num_channels ); module.set_num_channels( num_channels );
panning_offset = 96 + num_pattern_orders + num_instruments * 2 + num_patterns * 2; panning_offset = 96 + num_pattern_orders + num_instruments * 2 + num_patterns * 2;
for( channel_idx = 0; channel_idx < 32; channel_idx++ ) { for( channel_idx = 0; channel_idx < 32; channel_idx++ ) {
if( channel_map[ channel_idx ] < 0 ) continue; if( channel_map[ channel_idx ] < 0 ) continue;
panning = 7; panning = 7;
if( stereo_mode ) { if( stereo_mode ) {
panning = 12; panning = 12;
if( ( s3m_file[ 64 + channel_idx ] & 0xFF ) < 8 ) { if( ( s3m_file[ 64 + channel_idx ] & 0xFF ) < 8 ) {
panning = 3; panning = 3;
} }
} }
if( default_panning ) { if( default_panning ) {
flags = s3m_file[ panning_offset + channel_idx ] & 0xFF; flags = s3m_file[ panning_offset + channel_idx ] & 0xFF;
if( ( flags & 0x20 ) == 0x20 ) { if( ( flags & 0x20 ) == 0x20 ) {
panning = flags & 0xF; panning = flags & 0xF;
} }
} }
module.set_initial_panning( channel_map[ channel_idx ], panning * 17 ); module.set_initial_panning( channel_map[ channel_idx ], panning * 17 );
} }
sequence = read_s3m_sequence( s3m_file ); sequence = read_s3m_sequence( s3m_file );
module.set_sequence_length( sequence.length ); module.set_sequence_length( sequence.length );
for( order_idx = 0; order_idx < sequence.length; order_idx++ ) { for( order_idx = 0; order_idx < sequence.length; order_idx++ ) {
module.set_sequence( order_idx, sequence[ order_idx ] ); module.set_sequence( order_idx, sequence[ order_idx ] );
} }
module.set_num_instruments( num_instruments ); module.set_num_instruments( num_instruments );
for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) { for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) {
instrument = read_s3m_instrument( s3m_file, instrument_idx, signed_samples ); instrument = read_s3m_instrument( s3m_file, instrument_idx, signed_samples );
module.set_instrument( instrument_idx + 1, instrument ); module.set_instrument( instrument_idx + 1, instrument );
} }
module.set_num_patterns( num_patterns ); module.set_num_patterns( num_patterns );
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
module.set_pattern( pattern_idx, read_s3m_pattern( s3m_file, pattern_idx, channel_map ) ); module.set_pattern( pattern_idx, read_s3m_pattern( s3m_file, pattern_idx, channel_map ) );
} }
return module; return module;
} }
private static int[] read_s3m_sequence( byte[] s3m_file ) { private static int[] read_s3m_sequence( byte[] s3m_file ) {
int num_pattern_orders, sequence_length; int num_pattern_orders, sequence_length;
int sequence_idx, order_idx, pattern_order; int sequence_idx, order_idx, pattern_order;
int[] sequence; int[] sequence;
num_pattern_orders = get_num_pattern_orders( s3m_file ); num_pattern_orders = get_num_pattern_orders( s3m_file );
sequence_length = 0; sequence_length = 0;
for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) { for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) {
pattern_order = s3m_file[ 96 + order_idx ] & 0xFF; pattern_order = s3m_file[ 96 + order_idx ] & 0xFF;
if( pattern_order == 255 ) { if( pattern_order == 255 ) {
break; break;
} else if( pattern_order < 254 ) { } else if( pattern_order < 254 ) {
sequence_length += 1; sequence_length += 1;
} }
} }
sequence = new int[ sequence_length ]; sequence = new int[ sequence_length ];
sequence_idx = 0; sequence_idx = 0;
for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) { for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) {
pattern_order = s3m_file[ 96 + order_idx ] & 0xFF; pattern_order = s3m_file[ 96 + order_idx ] & 0xFF;
if( pattern_order == 255 ) { if( pattern_order == 255 ) {
break; break;
} else if( pattern_order < 254 ) { } else if( pattern_order < 254 ) {
sequence[ sequence_idx ] = pattern_order; sequence[ sequence_idx ] = pattern_order;
sequence_idx += 1; sequence_idx += 1;
} }
} }
return sequence; return sequence;
} }
private static Instrument read_s3m_instrument( byte[] s3m_file, int instrument_idx, boolean signed_samples ) { private static Instrument read_s3m_instrument( byte[] s3m_file, int instrument_idx, boolean signed_samples ) {
int instrument_offset; int instrument_offset;
int sample_data_offset, sample_data_length; int sample_data_offset, sample_data_length;
int loop_start, loop_length, c2_rate, sample_idx, amplitude; int loop_start, loop_length, c2_rate, sample_idx, amplitude;
boolean sixteen_bit; boolean sixteen_bit;
Instrument instrument; Instrument instrument;
Sample sample; Sample sample;
short[] sample_data; short[] sample_data;
instrument_offset = get_instrument_offset( s3m_file, instrument_idx ); instrument_offset = get_instrument_offset( s3m_file, instrument_idx );
instrument = new Instrument(); instrument = new Instrument();
instrument.name = ascii_text( s3m_file, instrument_offset + 48, 28 ); instrument.name = ascii_text( s3m_file, instrument_offset + 48, 28 );
sample = new Sample(); sample = new Sample();
if( s3m_file[ instrument_offset ] == 1 ) { if( s3m_file[ instrument_offset ] == 1 ) {
sample_data_length = get_sample_data_length( s3m_file, instrument_offset ); sample_data_length = get_sample_data_length( s3m_file, instrument_offset );
loop_start = unsigned_short_le( s3m_file, instrument_offset + 20 ); loop_start = unsigned_short_le( s3m_file, instrument_offset + 20 );
loop_length = unsigned_short_le( s3m_file, instrument_offset + 24 ) - loop_start; loop_length = unsigned_short_le( s3m_file, instrument_offset + 24 ) - loop_start;
sample.volume = s3m_file[ instrument_offset + 28 ] & 0xFF; sample.volume = s3m_file[ instrument_offset + 28 ] & 0xFF;
if( s3m_file[ instrument_offset + 30 ] != 0 ) { if( s3m_file[ instrument_offset + 30 ] != 0 ) {
throw new IllegalArgumentException( "ScreamTracker3: Packed samples not supported!" ); throw new IllegalArgumentException( "ScreamTracker3: Packed samples not supported!" );
} }
if( ( s3m_file[ instrument_offset + 31 ] & 0x01 ) == 0 ) { if( ( s3m_file[ instrument_offset + 31 ] & 0x01 ) == 0 ) {
loop_length = 0; loop_length = 0;
} }
if( ( s3m_file[ instrument_offset + 31 ] & 0x02 ) != 0 ) { if( ( s3m_file[ instrument_offset + 31 ] & 0x02 ) != 0 ) {
throw new IllegalArgumentException( "ScreamTracker3: Stereo samples not supported!" ); throw new IllegalArgumentException( "ScreamTracker3: Stereo samples not supported!" );
} }
sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0; sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0;
c2_rate = unsigned_short_le( s3m_file, instrument_offset + 32 ); c2_rate = unsigned_short_le( s3m_file, instrument_offset + 32 );
sample.transpose = LogTable.log_2( c2_rate ) - LogTable.log_2( 8363 ); sample.transpose = LogTable.log_2( c2_rate ) - LogTable.log_2( 8363 );
sample_data_offset = get_sample_data_offset( s3m_file, instrument_offset ); sample_data_offset = get_sample_data_offset( s3m_file, instrument_offset );
if( sixteen_bit ) { if( sixteen_bit ) {
if( signed_samples ) { if( signed_samples ) {
throw new IllegalArgumentException( "ScreamTracker3: Signed 16-bit samples not supported!" ); throw new IllegalArgumentException( "ScreamTracker3: Signed 16-bit samples not supported!" );
} }
sample_data_length >>= 1; sample_data_length >>= 1;
sample_data = new short[ sample_data_length ]; sample_data = new short[ sample_data_length ];
for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) { for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) {
amplitude = s3m_file[ sample_data_offset + sample_idx * 2 ] & 0xFF; amplitude = s3m_file[ sample_data_offset + sample_idx * 2 ] & 0xFF;
amplitude |= ( s3m_file[ sample_data_offset + sample_idx * 2 + 1 ] & 0xFF ) << 8; amplitude |= ( s3m_file[ sample_data_offset + sample_idx * 2 + 1 ] & 0xFF ) << 8;
sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 ); sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 );
} }
} else { } else {
sample_data = new short[ sample_data_length ]; sample_data = new short[ sample_data_length ];
if( signed_samples ) { if( signed_samples ) {
for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) { for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) {
amplitude = s3m_file[ sample_data_offset + sample_idx ] << 8; amplitude = s3m_file[ sample_data_offset + sample_idx ] << 8;
sample_data[ sample_idx ] = ( short ) amplitude; sample_data[ sample_idx ] = ( short ) amplitude;
} }
} else { } else {
for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) { for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) {
amplitude = ( s3m_file[ sample_data_offset + sample_idx ] & 0xFF ) << 8; amplitude = ( s3m_file[ sample_data_offset + sample_idx ] & 0xFF ) << 8;
sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 ); sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 );
} }
} }
} }
sample.set_sample_data( sample_data, loop_start, loop_length, false ); sample.set_sample_data( sample_data, loop_start, loop_length, false );
} }
instrument.set_num_samples( 1 ); instrument.set_num_samples( 1 );
instrument.set_sample( 0, sample ); instrument.set_sample( 0, sample );
return instrument; return instrument;
} }
private static Pattern read_s3m_pattern( byte[] s3m_file, int pattern_idx, int[] channel_map ) { private static Pattern read_s3m_pattern( byte[] s3m_file, int pattern_idx, int[] channel_map ) {
int pattern_offset; int pattern_offset;
int num_channels, num_notes; int num_channels, num_notes;
int row_idx, channel_idx, note_idx; int row_idx, channel_idx, note_idx;
int token, key, volume_column, effect, effect_param; int token, key, volume_column, effect, effect_param;
byte[] pattern_data; byte[] pattern_data;
Pattern pattern; Pattern pattern;
num_channels = 0; num_channels = 0;
for( channel_idx = 0; channel_idx < 32; channel_idx++ ) { for( channel_idx = 0; channel_idx < 32; channel_idx++ ) {
if( channel_map[ channel_idx ] >= num_channels ) { if( channel_map[ channel_idx ] >= num_channels ) {
num_channels = channel_idx + 1; num_channels = channel_idx + 1;
} }
} }
num_notes = num_channels * 64; num_notes = num_channels * 64;
pattern_data = new byte[ num_notes * 5 ]; pattern_data = new byte[ num_notes * 5 ];
row_idx = 0; row_idx = 0;
pattern_offset = get_pattern_offset( s3m_file, pattern_idx ) + 2; pattern_offset = get_pattern_offset( s3m_file, pattern_idx ) + 2;
while( row_idx < 64 ) { while( row_idx < 64 ) {
token = s3m_file[ pattern_offset ] & 0xFF; token = s3m_file[ pattern_offset ] & 0xFF;
pattern_offset += 1; pattern_offset += 1;
if( token > 0 ) { if( token > 0 ) {
channel_idx = channel_map[ token & 0x1F ]; channel_idx = channel_map[ token & 0x1F ];
note_idx = ( num_channels * row_idx + channel_idx ) * 5; note_idx = ( num_channels * row_idx + channel_idx ) * 5;
if( ( token & 0x20 ) == 0x20 ) { if( ( token & 0x20 ) == 0x20 ) {
/* Key + Instrument.*/ /* Key + Instrument.*/
if( channel_idx >= 0 ) { if( channel_idx >= 0 ) {
key = s3m_file[ pattern_offset ] & 0xFF; key = s3m_file[ pattern_offset ] & 0xFF;
if( key == 255 ) { if( key == 255 ) {
key = 0; key = 0;
} else if( key == 254 ) { } else if( key == 254 ) {
key = 97; key = 97;
} else { } else {
key = ( ( key & 0xF0 ) >> 4 ) * 12 + ( key & 0x0F ) + 1; key = ( ( key & 0xF0 ) >> 4 ) * 12 + ( key & 0x0F ) + 1;
while( key > 96 ) { while( key > 96 ) {
key = key - 12; key = key - 12;
} }
} }
pattern_data[ note_idx ] = ( byte ) key; pattern_data[ note_idx ] = ( byte ) key;
pattern_data[ note_idx + 1 ] = s3m_file[ pattern_offset + 1 ]; pattern_data[ note_idx + 1 ] = s3m_file[ pattern_offset + 1 ];
} }
pattern_offset += 2; pattern_offset += 2;
} }
if( ( token & 0x40 ) == 0x40 ) { if( ( token & 0x40 ) == 0x40 ) {
/* Volume.*/ /* Volume.*/
if( channel_idx >= 0 ) { if( channel_idx >= 0 ) {
volume_column = ( s3m_file[ pattern_offset ] & 0xFF ) + 0x10; volume_column = ( s3m_file[ pattern_offset ] & 0xFF ) + 0x10;
pattern_data[ note_idx + 2 ] = ( byte ) volume_column; pattern_data[ note_idx + 2 ] = ( byte ) volume_column;
} }
pattern_offset += 1; pattern_offset += 1;
} }
if( ( token & 0x80 ) == 0x80 ) { if( ( token & 0x80 ) == 0x80 ) {
/* Effect + Param.*/ /* Effect + Param.*/
if( channel_idx >= 0 ) { if( channel_idx >= 0 ) {
effect = s3m_file[ pattern_offset ] & 0xFF; effect = s3m_file[ pattern_offset ] & 0xFF;
effect_param = s3m_file[ pattern_offset + 1 ] & 0xFF; effect_param = s3m_file[ pattern_offset + 1 ] & 0xFF;
effect = effect_map[ effect & 0x1F ]; effect = effect_map[ effect & 0x1F ];
if( effect == 0xFF ) { if( effect == 0xFF ) {
effect = 0; effect = 0;
effect_param = 0; effect_param = 0;
} }
if( effect == 0x0E ) { if( effect == 0x0E ) {
effect = effect_s_map[ ( effect_param & 0xF0 ) >> 4 ]; effect = effect_s_map[ ( effect_param & 0xF0 ) >> 4 ];
effect_param = effect_param & 0x0F; effect_param = effect_param & 0x0F;
switch( effect ) { switch( effect ) {
case 0x08: case 0x08:
effect = 0x08; effect = 0x08;
effect_param = effect_param * 17; effect_param = effect_param * 17;
break; break;
case 0x09: case 0x09:
effect = 0x08; effect = 0x08;
if( effect_param > 7 ) { if( effect_param > 7 ) {
effect_param -= 8; effect_param -= 8;
} else { } else {
effect_param += 8; effect_param += 8;
} }
effect_param = effect_param * 17; effect_param = effect_param * 17;
break; break;
case 0xFF: case 0xFF:
effect = 0; effect = 0;
effect_param = 0; effect_param = 0;
break; break;
default: default:
effect_param = ( ( effect & 0x0F ) << 4 ) | ( effect_param & 0x0F ); effect_param = ( ( effect & 0x0F ) << 4 ) | ( effect_param & 0x0F );
effect = 0x0E; effect = 0x0E;
break; break;
} }
} }
pattern_data[ note_idx + 3 ] = ( byte ) effect; pattern_data[ note_idx + 3 ] = ( byte ) effect;
pattern_data[ note_idx + 4 ] = ( byte ) effect_param; pattern_data[ note_idx + 4 ] = ( byte ) effect_param;
} }
pattern_offset += 2; pattern_offset += 2;
} }
} else { } else {
row_idx += 1; row_idx += 1;
} }
} }
pattern = new Pattern(); pattern = new Pattern();
pattern.num_rows = 64; pattern.num_rows = 64;
pattern.set_pattern_data( pattern_data ); pattern.set_pattern_data( pattern_data );
return pattern; return pattern;
} }
private static byte[] read_s3m_file( byte[] header_96_bytes, DataInput data_input ) throws IOException { private static byte[] read_s3m_file( byte[] header_96_bytes, DataInput data_input ) throws IOException {
int s3m_file_length; int s3m_file_length;
int num_pattern_orders, num_instruments, num_patterns; int num_pattern_orders, num_instruments, num_patterns;
int instrument_idx, pattern_idx; int instrument_idx, pattern_idx;
int instrument_offset, sample_data_offset, pattern_offset; int instrument_offset, sample_data_offset, pattern_offset;
byte[] s3m_file; byte[] s3m_file;
if( !is_s3m( header_96_bytes ) ) { if( !is_s3m( header_96_bytes ) ) {
throw new IllegalArgumentException( "ScreamTracker3: Not an S3M file!" ); throw new IllegalArgumentException( "ScreamTracker3: Not an S3M file!" );
} }
s3m_file = header_96_bytes; s3m_file = header_96_bytes;
s3m_file_length = header_96_bytes.length; s3m_file_length = header_96_bytes.length;
num_pattern_orders = get_num_pattern_orders( s3m_file ); num_pattern_orders = get_num_pattern_orders( s3m_file );
num_instruments = get_num_instruments( s3m_file ); num_instruments = get_num_instruments( s3m_file );
num_patterns = get_num_patterns( s3m_file ); num_patterns = get_num_patterns( s3m_file );
s3m_file_length += num_pattern_orders; s3m_file_length += num_pattern_orders;
s3m_file_length += num_instruments * 2; s3m_file_length += num_instruments * 2;
s3m_file_length += num_patterns * 2; s3m_file_length += num_patterns * 2;
/* Read enough of file to calculate the length.*/ /* Read enough of file to calculate the length.*/
s3m_file = read_more( s3m_file, s3m_file_length, data_input ); s3m_file = read_more( s3m_file, s3m_file_length, data_input );
for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) { for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) {
instrument_offset = get_instrument_offset( s3m_file, instrument_idx ); instrument_offset = get_instrument_offset( s3m_file, instrument_idx );
instrument_offset += 80; instrument_offset += 80;
if( instrument_offset > s3m_file_length ) { if( instrument_offset > s3m_file_length ) {
s3m_file_length = instrument_offset; s3m_file_length = instrument_offset;
} }
} }
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
pattern_offset = get_pattern_offset( s3m_file, pattern_idx ); pattern_offset = get_pattern_offset( s3m_file, pattern_idx );
pattern_offset += 2; pattern_offset += 2;
if( pattern_offset > s3m_file_length ) { if( pattern_offset > s3m_file_length ) {
s3m_file_length = pattern_offset; s3m_file_length = pattern_offset;
} }
} }
s3m_file = read_more( s3m_file, s3m_file_length, data_input ); s3m_file = read_more( s3m_file, s3m_file_length, data_input );
/* Read rest of file.*/ /* Read rest of file.*/
for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) { for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) {
instrument_offset = get_instrument_offset( s3m_file, instrument_idx ); instrument_offset = get_instrument_offset( s3m_file, instrument_idx );
sample_data_offset = get_sample_data_offset( s3m_file, instrument_offset ); sample_data_offset = get_sample_data_offset( s3m_file, instrument_offset );
sample_data_offset += get_sample_data_length( s3m_file, instrument_offset ); sample_data_offset += get_sample_data_length( s3m_file, instrument_offset );
if( sample_data_offset > s3m_file_length ) { if( sample_data_offset > s3m_file_length ) {
s3m_file_length = sample_data_offset; s3m_file_length = sample_data_offset;
} }
} }
for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) {
pattern_offset = get_pattern_offset( s3m_file, pattern_idx ); pattern_offset = get_pattern_offset( s3m_file, pattern_idx );
pattern_offset += get_pattern_length( s3m_file, pattern_offset ); pattern_offset += get_pattern_length( s3m_file, pattern_offset );
pattern_offset += 2; pattern_offset += 2;
if( pattern_offset > s3m_file_length ) { if( pattern_offset > s3m_file_length ) {
s3m_file_length = pattern_offset; s3m_file_length = pattern_offset;
} }
} }
s3m_file = read_more( s3m_file, s3m_file_length, data_input ); s3m_file = read_more( s3m_file, s3m_file_length, data_input );
return s3m_file; return s3m_file;
} }
private static int get_num_pattern_orders( byte[] s3m_file ) { private static int get_num_pattern_orders( byte[] s3m_file ) {
int num_pattern_orders; int num_pattern_orders;
num_pattern_orders = unsigned_short_le( s3m_file, 32 ); num_pattern_orders = unsigned_short_le( s3m_file, 32 );
return num_pattern_orders; return num_pattern_orders;
} }
private static int get_num_instruments( byte[] s3m_file ) { private static int get_num_instruments( byte[] s3m_file ) {
int num_instruments; int num_instruments;
num_instruments = unsigned_short_le( s3m_file, 34 ); num_instruments = unsigned_short_le( s3m_file, 34 );
return num_instruments; return num_instruments;
} }
private static int get_num_patterns( byte[] s3m_file ) { private static int get_num_patterns( byte[] s3m_file ) {
int num_patterns; int num_patterns;
num_patterns = unsigned_short_le( s3m_file, 36 ); num_patterns = unsigned_short_le( s3m_file, 36 );
return num_patterns; return num_patterns;
} }
private static int get_instrument_offset( byte[] s3m_file, int instrument_idx ) { private static int get_instrument_offset( byte[] s3m_file, int instrument_idx ) {
int instrument_offset, pointer_offset; int instrument_offset, pointer_offset;
pointer_offset = 96 + get_num_pattern_orders( s3m_file ); pointer_offset = 96 + get_num_pattern_orders( s3m_file );
instrument_offset = unsigned_short_le( s3m_file, pointer_offset + instrument_idx * 2 ) << 4; instrument_offset = unsigned_short_le( s3m_file, pointer_offset + instrument_idx * 2 ) << 4;
return instrument_offset; return instrument_offset;
} }
private static int get_sample_data_offset( byte[] s3m_file, int instrument_offset ) { private static int get_sample_data_offset( byte[] s3m_file, int instrument_offset ) {
int sample_data_offset; int sample_data_offset;
sample_data_offset = 0; sample_data_offset = 0;
if( s3m_file[ instrument_offset ] == 1 ) { if( s3m_file[ instrument_offset ] == 1 ) {
sample_data_offset = ( s3m_file[ instrument_offset + 13 ] & 0xFF ) << 20; sample_data_offset = ( s3m_file[ instrument_offset + 13 ] & 0xFF ) << 20;
sample_data_offset |= unsigned_short_le( s3m_file, instrument_offset + 14 ) << 4; sample_data_offset |= unsigned_short_le( s3m_file, instrument_offset + 14 ) << 4;
} }
return sample_data_offset; return sample_data_offset;
} }
private static int get_sample_data_length( byte[] s3m_file, int instrument_offset ) { private static int get_sample_data_length( byte[] s3m_file, int instrument_offset ) {
int sample_data_length; int sample_data_length;
boolean sixteen_bit; boolean sixteen_bit;
sample_data_length = 0; sample_data_length = 0;
if( s3m_file[ instrument_offset ] == 1 ) { if( s3m_file[ instrument_offset ] == 1 ) {
sample_data_length = unsigned_short_le( s3m_file, instrument_offset + 16 ); sample_data_length = unsigned_short_le( s3m_file, instrument_offset + 16 );
sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0; sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0;
if( sixteen_bit ) { if( sixteen_bit ) {
sample_data_length <<= 1; sample_data_length <<= 1;
} }
} }
return sample_data_length; return sample_data_length;
} }
private static int get_pattern_offset( byte[] s3m_file, int pattern_idx ) { private static int get_pattern_offset( byte[] s3m_file, int pattern_idx ) {
int pattern_offset, pointer_offset; int pattern_offset, pointer_offset;
pointer_offset = 96 + get_num_pattern_orders( s3m_file ); pointer_offset = 96 + get_num_pattern_orders( s3m_file );
pointer_offset += get_num_instruments( s3m_file ) * 2; pointer_offset += get_num_instruments( s3m_file ) * 2;
pattern_offset = unsigned_short_le( s3m_file, pointer_offset + pattern_idx * 2 ) << 4; pattern_offset = unsigned_short_le( s3m_file, pointer_offset + pattern_idx * 2 ) << 4;
return pattern_offset; return pattern_offset;
} }
private static int get_pattern_length( byte[] s3m_file, int pattern_offset ) { private static int get_pattern_length( byte[] s3m_file, int pattern_offset ) {
int pattern_length; int pattern_length;
pattern_length = unsigned_short_le( s3m_file, pattern_offset ); pattern_length = unsigned_short_le( s3m_file, pattern_offset );
return pattern_length; return pattern_length;
} }
private static byte[] read_more( byte[] old_data, int new_length, DataInput data_input ) throws IOException { private static byte[] read_more( byte[] old_data, int new_length, DataInput data_input ) throws IOException {
byte[] new_data; byte[] new_data;
new_data = old_data; new_data = old_data;
if( new_length > old_data.length ) { if( new_length > old_data.length ) {
new_data = new byte[ new_length ]; new_data = new byte[ new_length ];
System.arraycopy( old_data, 0, new_data, 0, old_data.length ); System.arraycopy( old_data, 0, new_data, 0, old_data.length );
try { try {
data_input.readFully( new_data, old_data.length, new_data.length - old_data.length ); data_input.readFully( new_data, old_data.length, new_data.length - old_data.length );
} catch( EOFException e ) { } catch( EOFException e ) {
System.out.println( "ScreamTracker3: Module has been truncated!" ); System.out.println( "ScreamTracker3: Module has been truncated!" );
} }
} }
return new_data; return new_data;
} }
private static int unsigned_short_le( byte[] buffer, int offset ) { private static int unsigned_short_le( byte[] buffer, int offset ) {
int value; int value;
value = buffer[ offset ] & 0xFF; value = buffer[ offset ] & 0xFF;
value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 ); value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 );
return value; return value;
} }
private static String ascii_text( byte[] buffer, int offset, int length ) { private static String ascii_text( byte[] buffer, int offset, int length ) {
int idx, chr; int idx, chr;
byte[] string_buffer; byte[] string_buffer;
String string; String string;
string_buffer = new byte[ length ]; string_buffer = new byte[ length ];
for( idx = 0; idx < length; idx++ ) { for( idx = 0; idx < length; idx++ ) {
chr = buffer[ offset + idx ]; chr = buffer[ offset + idx ];
if( chr < 32 ) { if( chr < 32 ) {
chr = 32; chr = 32;
} }
string_buffer[ idx ] = ( byte ) chr; string_buffer[ idx ] = ( byte ) chr;
} }
try { try {
string = new String( string_buffer, 0, length, "ISO-8859-1" ); string = new String( string_buffer, 0, length, "ISO-8859-1" );
} catch( UnsupportedEncodingException e ) { } catch( UnsupportedEncodingException e ) {
string = ""; string = "";
} }
return string; return string;
} }
} }

View File

@ -1,109 +1,109 @@
package net.minecraft.src.forge; package net.minecraft.src.forge;
import net.minecraft.src.Entity; import net.minecraft.src.Entity;
import net.minecraft.src.SoundManager; import net.minecraft.src.SoundManager;
import net.minecraft.src.SoundPoolEntry; import net.minecraft.src.SoundPoolEntry;
public interface ISoundHandler public interface ISoundHandler
{ {
/** /**
* This event is raised by the SoundManager when it does its first setup of the * This event is raised by the SoundManager when it does its first setup of the
* SoundSystemConfig's codecs, use this function to add your own codecs. * SoundSystemConfig's codecs, use this function to add your own codecs.
* @param soundManager The SoundManager instance * @param soundManager The SoundManager instance
*/ */
void onSetupAudio(SoundManager soundManager); void onSetupAudio(SoundManager soundManager);
/** /**
* Raised by the SoundManager.loadSoundSettings, this would be a good place for * Raised by the SoundManager.loadSoundSettings, this would be a good place for
* adding your custom sounds to the SoundPool. * adding your custom sounds to the SoundPool.
* *
* @param soundManager The SoundManager instance * @param soundManager The SoundManager instance
*/ */
void onLoadSoundSettings(SoundManager soundManager); void onLoadSoundSettings(SoundManager soundManager);
/** /**
* Raised when the SoundManager tries to play a Background Music file, * Raised when the SoundManager tries to play a Background Music file,
* If you return null from this function it will prevent the sound from being played, * If you return null from this function it will prevent the sound from being played,
* you can return a different entry if you want to change the sound being played. * you can return a different entry if you want to change the sound being played.
* *
* If you do not want to change anything, just return the passed in entry. * If you do not want to change anything, just return the passed in entry.
* *
* @param soundManager The SoundManager instance * @param soundManager The SoundManager instance
* @param entry The current entry that will be played * @param entry The current entry that will be played
* @return The new sound entry to play, or the current one passed in. * @return The new sound entry to play, or the current one passed in.
*/ */
SoundPoolEntry onPlayBackgroundMusic(SoundManager soundManager, SoundPoolEntry entry); SoundPoolEntry onPlayBackgroundMusic(SoundManager soundManager, SoundPoolEntry entry);
/** /**
* Raised when the SoundManager tries to play a 'Streaming' file, * Raised when the SoundManager tries to play a 'Streaming' file,
* in vanilla it is only the Jukebox that uses this function. * in vanilla it is only the Jukebox that uses this function.
* *
* If you return null from this function it will prevent the sound from being played, * If you return null from this function it will prevent the sound from being played,
* you can return a different entry if you want to change the sound being played. * you can return a different entry if you want to change the sound being played.
* *
* If you do not want to change anything, just return the passed in entry. * If you do not want to change anything, just return the passed in entry.
* *
* @param soundManager The SoundManager instance * @param soundManager The SoundManager instance
* @param entry The current entry that will be played * @param entry The current entry that will be played
* @param soundName The name of the request sound * @param soundName The name of the request sound
* @param x The X position where the sound will be played * @param x The X position where the sound will be played
* @param y The Y position where the sound will be played * @param y The Y position where the sound will be played
* @param z The Z position where the sound will be played * @param z The Z position where the sound will be played
* @return The new sound entry to play, or the current one passed in. * @return The new sound entry to play, or the current one passed in.
*/ */
SoundPoolEntry onPlayStreaming(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z); SoundPoolEntry onPlayStreaming(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z);
/*** /***
* Raised when the SoundManager tries to play a normal sound, * Raised when the SoundManager tries to play a normal sound,
* dogs barking, footsteps, etc. THe majority of all sounds during normal game play. * dogs barking, footsteps, etc. THe majority of all sounds during normal game play.
* *
* If you return null from this function it will prevent the sound from being played, * If you return null from this function it will prevent the sound from being played,
* you can return a different entry if you want to change the sound being played. * you can return a different entry if you want to change the sound being played.
* *
* If you do not want to change anything, just return the passed in entry. * If you do not want to change anything, just return the passed in entry.
* *
* @param soundManager The SoundManager instance * @param soundManager The SoundManager instance
* @param entry The current entry that will be played * @param entry The current entry that will be played
* @param soundName The name of the request sound * @param soundName The name of the request sound
* @param x The X position where the sound will be played * @param x The X position where the sound will be played
* @param y The Y position where the sound will be played * @param y The Y position where the sound will be played
* @param z The Z position where the sound will be played * @param z The Z position where the sound will be played
* @param volume The sound's volume, between 0.0 and 1.0 * @param volume The sound's volume, between 0.0 and 1.0
* @param pitch The sound's pitch * @param pitch The sound's pitch
* @return The new sound entry to play, or the current one passed in. * @return The new sound entry to play, or the current one passed in.
*/ */
SoundPoolEntry onPlaySound(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z, float volume, float pitch); SoundPoolEntry onPlaySound(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z, float volume, float pitch);
/** /**
* Raised when the SoundManager tries to play a effect sound, * Raised when the SoundManager tries to play a effect sound,
* currently the only known sounds are 'random.click' when a GUI button is clicked, * currently the only known sounds are 'random.click' when a GUI button is clicked,
* or 'portal.trigger' and 'portal.travel' when the player is near/inside a portal. * or 'portal.trigger' and 'portal.travel' when the player is near/inside a portal.
* *
* If you return null from this function it will prevent the sound from being played, * If you return null from this function it will prevent the sound from being played,
* you can return a different entry if you want to change the sound being played. * you can return a different entry if you want to change the sound being played.
* *
* If you do not want to change anything, just return the passed in entry. * If you do not want to change anything, just return the passed in entry.
* *
* @param soundManager The SoundManager instance * @param soundManager The SoundManager instance
* @param entry The current entry that will be played * @param entry The current entry that will be played
* @param soundName The name of the request sound * @param soundName The name of the request sound
* @param volume The sound's volume, between 0.0 and 1.0 * @param volume The sound's volume, between 0.0 and 1.0
* @param pitch The sound's pitch * @param pitch The sound's pitch
* @return The new sound entry to play, or the current one passed in. * @return The new sound entry to play, or the current one passed in.
*/ */
SoundPoolEntry onPlaySoundEffect(SoundManager soundManager, SoundPoolEntry entry, String soundName, float volume, float pitch); SoundPoolEntry onPlaySoundEffect(SoundManager soundManager, SoundPoolEntry entry, String soundName, float volume, float pitch);
/** /**
* Raised when an entity attempts to play a sound via World's playSoundAtEntity * Raised when an entity attempts to play a sound via World's playSoundAtEntity
* function. This is so that additional data about the state of the entity can * function. This is so that additional data about the state of the entity can
* be obtained efficiently without using AABBs. An important thing to note: * be obtained efficiently without using AABBs. An important thing to note:
* This hook will be called even if the sound is off. * This hook will be called even if the sound is off.
* *
* @param entity The entity that the sound should be played at. Always the calling Entity or the Player. * @param entity The entity that the sound should be played at. Always the calling Entity or the Player.
* @param soundName The name of the requested sound. * @param soundName The name of the requested sound.
* @param volume The sound's volume, between 0.0 and 1.0. * @param volume The sound's volume, between 0.0 and 1.0.
* @param pitch The sound's pitch * @param pitch The sound's pitch
* @return The sound to play, null to cancel the event. * @return The sound to play, null to cancel the event.
*/ */
String onPlaySoundAtEntity(Entity entity, String soundName, float volume, float pitch); String onPlaySoundAtEntity(Entity entity, String soundName, float volume, float pitch);
} }

View File

@ -1,6 +1,6 @@
package net.minecraft.src.forge; package net.minecraft.src.forge;
public interface ITextureLoadHandler public interface ITextureLoadHandler
{ {
public void onTextureLoad(String textureName, int textureID); public void onTextureLoad(String textureName, int textureID);
} }

View File

@ -1,268 +1,268 @@
package net.minecraft.src.forge; package net.minecraft.src.forge;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import paulscode.sound.SoundSystemConfig; import paulscode.sound.SoundSystemConfig;
import paulscode.sound.codecs.CodecIBXM; import paulscode.sound.codecs.CodecIBXM;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.src.*; import net.minecraft.src.*;
public class ModCompatibilityClient public class ModCompatibilityClient
{ {
/** /**
* Trys to get the class for the specified name, will also try the * Trys to get the class for the specified name, will also try the
* net.minecraft.src package in case we are in MCP * net.minecraft.src package in case we are in MCP
* Returns null if not found. * Returns null if not found.
* *
* @param name The class name * @param name The class name
* @return The Class, or null if not found * @return The Class, or null if not found
*/ */
private static Class getClass(String name) private static Class getClass(String name)
{ {
try try
{ {
return Class.forName(name); return Class.forName(name);
} }
catch (Exception e) catch (Exception e)
{ {
try try
{ {
return Class.forName("net.minecraft.src." + name); return Class.forName("net.minecraft.src." + name);
} }
catch (Exception e2) catch (Exception e2)
{ {
return null; return null;
} }
} }
} }
/************************************************************************************************ /************************************************************************************************
* Risugami's AudioMod Compatibility * Risugami's AudioMod Compatibility
* http://www.minecraftforum.net/topic/75440- * http://www.minecraftforum.net/topic/75440-
* *
* AudioMod adds a few extra codecs, loads audio from /resources/mods/*, * AudioMod adds a few extra codecs, loads audio from /resources/mods/*,
* introduces the concept of 'cave' sounds, which are determined by if * introduces the concept of 'cave' sounds, which are determined by if
* the player is underneath a solid block. * the player is underneath a solid block.
* *
* It also lowers the interval between background music songs to 6000 * It also lowers the interval between background music songs to 6000
*/ */
public static SoundPool audioModSoundPoolCave; public static SoundPool audioModSoundPoolCave;
/** /**
* Populates the sound pools with with sounds from the /resources/mods folder * Populates the sound pools with with sounds from the /resources/mods folder
* And sets the interval between background music to 6000 * And sets the interval between background music to 6000
* *
* @param mngr The SoundManager instance * @param mngr The SoundManager instance
*/ */
public static void audioModLoad(SoundManager mngr) public static void audioModLoad(SoundManager mngr)
{ {
audioModSoundPoolCave = new SoundPool(); audioModSoundPoolCave = new SoundPool();
audioModLoadModAudio("resources/mod/sound", mngr.getSoundsPool()); audioModLoadModAudio("resources/mod/sound", mngr.getSoundsPool());
audioModLoadModAudio("resources/mod/streaming", mngr.getStreamingPool()); audioModLoadModAudio("resources/mod/streaming", mngr.getStreamingPool());
audioModLoadModAudio("resources/mod/music", mngr.getMusicPool()); audioModLoadModAudio("resources/mod/music", mngr.getMusicPool());
audioModLoadModAudio("resources/mod/cavemusic", audioModSoundPoolCave); audioModLoadModAudio("resources/mod/cavemusic", audioModSoundPoolCave);
if (mngr.MUSIC_INTERVAL == 12000) if (mngr.MUSIC_INTERVAL == 12000)
{ {
mngr.MUSIC_INTERVAL = 6000; mngr.MUSIC_INTERVAL = 6000;
} }
} }
/** /**
* Walks the given path in the Minecraft app directory and adds audio to the SoundPool * Walks the given path in the Minecraft app directory and adds audio to the SoundPool
* @param path The path to walk * @param path The path to walk
* @param pool The pool to add sound to * @param pool The pool to add sound to
*/ */
private static void audioModLoadModAudio(String path, SoundPool pool) private static void audioModLoadModAudio(String path, SoundPool pool)
{ {
File folder = new File(Minecraft.getMinecraftDir(), path); File folder = new File(Minecraft.getMinecraftDir(), path);
try try
{ {
audioModWalkFolder(folder, folder, pool); audioModWalkFolder(folder, folder, pool);
} }
catch (IOException ex) catch (IOException ex)
{ {
ModLoader.getLogger().fine("Loading Mod audio failed for folder: " + path); ModLoader.getLogger().fine("Loading Mod audio failed for folder: " + path);
ModLoader.getLogger().fine(ex.toString()); ModLoader.getLogger().fine(ex.toString());
ex.printStackTrace(); ex.printStackTrace();
} }
} }
/** /**
* Walks the folder path recursively and calls pool.addSound on any file it finds. * Walks the folder path recursively and calls pool.addSound on any file it finds.
* *
* @param base The base path for the folder, determines the name when calling addSound * @param base The base path for the folder, determines the name when calling addSound
* @param folder The current folder * @param folder The current folder
* @param pool The SoundPool to add the sound to * @param pool The SoundPool to add the sound to
* @throws IOException * @throws IOException
*/ */
private static void audioModWalkFolder(File base, File folder, SoundPool pool) throws IOException private static void audioModWalkFolder(File base, File folder, SoundPool pool) throws IOException
{ {
if (folder.exists() || folder.mkdirs()) if (folder.exists() || folder.mkdirs())
{ {
for (File file : folder.listFiles()) for (File file : folder.listFiles())
{ {
if (!file.getName().startsWith(".")) if (!file.getName().startsWith("."))
{ {
if (file.isDirectory()) if (file.isDirectory())
{ {
audioModWalkFolder(base, file, pool); audioModWalkFolder(base, file, pool);
} }
else if (file.isFile()) else if (file.isFile())
{ {
String subpath = file.getPath().substring(base.getPath().length() + 1).replace('\\', '/'); String subpath = file.getPath().substring(base.getPath().length() + 1).replace('\\', '/');
pool.addSound(subpath, file); pool.addSound(subpath, file);
} }
} }
} }
} }
} }
/** /**
* Adds the IBXM codec and associates it with .xm, .s3m, and .mod * Adds the IBXM codec and associates it with .xm, .s3m, and .mod
*/ */
public static void audioModAddCodecs() public static void audioModAddCodecs()
{ {
SoundSystemConfig.setCodec("xm", CodecIBXM.class); SoundSystemConfig.setCodec("xm", CodecIBXM.class);
SoundSystemConfig.setCodec("s3m", CodecIBXM.class); SoundSystemConfig.setCodec("s3m", CodecIBXM.class);
SoundSystemConfig.setCodec("mod", CodecIBXM.class); SoundSystemConfig.setCodec("mod", CodecIBXM.class);
} }
/** /**
* If the current player is underground, it picks a random song from the cave sound pool, * If the current player is underground, it picks a random song from the cave sound pool,
* if they are not it returns the passed in entry. * if they are not it returns the passed in entry.
* *
* @param soundManager The SoundManager instance * @param soundManager The SoundManager instance
* @param current The currently selected entry * @param current The currently selected entry
* @return A soundPool entry to be played as the background music * @return A soundPool entry to be played as the background music
*/ */
public static SoundPoolEntry audioModPickBackgroundMusic(SoundManager soundManager, SoundPoolEntry current) public static SoundPoolEntry audioModPickBackgroundMusic(SoundManager soundManager, SoundPoolEntry current)
{ {
Minecraft mc = ModLoader.getMinecraftInstance(); Minecraft mc = ModLoader.getMinecraftInstance();
if (mc != null && mc.theWorld != null && audioModSoundPoolCave != null) if (mc != null && mc.theWorld != null && audioModSoundPoolCave != null)
{ {
Entity ent = mc.renderViewEntity; Entity ent = mc.renderViewEntity;
int x = MathHelper.func_40346_b(ent.posX); int x = MathHelper.func_40346_b(ent.posX);
int y = MathHelper.func_40346_b(ent.posY); int y = MathHelper.func_40346_b(ent.posY);
int z = MathHelper.func_40346_b(ent.posZ); int z = MathHelper.func_40346_b(ent.posZ);
return (mc.theWorld.canBlockSeeTheSky(x, y, z) ? current : audioModSoundPoolCave.getRandomSound()); return (mc.theWorld.canBlockSeeTheSky(x, y, z) ? current : audioModSoundPoolCave.getRandomSound());
} }
return current; return current;
} }
/*********************************************************************************************************** /***********************************************************************************************************
* SDK's ModLoaderMP * SDK's ModLoaderMP
* http://www.minecraftforum.net/topic/86765- * http://www.minecraftforum.net/topic/86765-
* *
* ModLoaderMP was supposed to be a reliable server side version of ModLoader, however it has * ModLoaderMP was supposed to be a reliable server side version of ModLoader, however it has
* gotten the reputation of being really slow to update. Never having bugfixes, breaking compatibility * gotten the reputation of being really slow to update. Never having bugfixes, breaking compatibility
* with the client side ModLoader. * with the client side ModLoader.
* *
* So we have replaced it with our own system called FML (Forge ModLoader) * So we have replaced it with our own system called FML (Forge ModLoader)
* it is a stand alone mod, that Forge relies on, and that is open source/community driven. * it is a stand alone mod, that Forge relies on, and that is open source/community driven.
* https://github.com/cpw/FML * https://github.com/cpw/FML
* *
* However, for compatibilities sake, we provide the ModLoaderMP's hooks so that the end user * However, for compatibilities sake, we provide the ModLoaderMP's hooks so that the end user
* does not need to make a choice between the two on the client side. * does not need to make a choice between the two on the client side.
**/ **/
private static int isMLMPInstalled = -1; private static int isMLMPInstalled = -1;
/** /**
* Determine if ModLoaderMP is installed by checking for the existence of the BaseModMp class. * Determine if ModLoaderMP is installed by checking for the existence of the BaseModMp class.
* @return True if BaseModMp was installed (indicating the existance of MLMP) * @return True if BaseModMp was installed (indicating the existance of MLMP)
*/ */
public static boolean isMLMPInstalled() public static boolean isMLMPInstalled()
{ {
if (isMLMPInstalled == -1) if (isMLMPInstalled == -1)
{ {
isMLMPInstalled = (getClass("ModLoaderMp") != null ? 1 : 0); isMLMPInstalled = (getClass("ModLoaderMp") != null ? 1 : 0);
} }
return isMLMPInstalled == 1; return isMLMPInstalled == 1;
} }
/** /**
* Attempts to spawn a vehicle using ModLoaderMP's vehicle spawn registry, if MLMP is not installed * Attempts to spawn a vehicle using ModLoaderMP's vehicle spawn registry, if MLMP is not installed
* it returns the passed in currentEntity * it returns the passed in currentEntity
* *
* @param type The Type ID of the vehicle * @param type The Type ID of the vehicle
* @param world The current world * @param world The current world
* @param x The spawn X position * @param x The spawn X position
* @param y The spawn Y position * @param y The spawn Y position
* @param z The spawn Z position * @param z The spawn Z position
* @param thrower The entity that spawned the vehicle {possibly null} * @param thrower The entity that spawned the vehicle {possibly null}
* @param currentEntity The current value to return if MLMP is not installed * @param currentEntity The current value to return if MLMP is not installed
* @return The new spawned entity * @return The new spawned entity
* @throws Exception * @throws Exception
*/ */
public static Object mlmpVehicleSpawn(int type, World world, double x, double y, double z, Entity thrower, Object currentEntity) throws Exception public static Object mlmpVehicleSpawn(int type, World world, double x, double y, double z, Entity thrower, Object currentEntity) throws Exception
{ {
Class mlmp = getClass("ModLoaderMp"); Class mlmp = getClass("ModLoaderMp");
if (!isMLMPInstalled() || mlmp == null) if (!isMLMPInstalled() || mlmp == null)
{ {
return currentEntity; return currentEntity;
} }
Object entry = mlmp.getDeclaredMethod("handleNetClientHandlerEntities", int.class).invoke(null, type); Object entry = mlmp.getDeclaredMethod("handleNetClientHandlerEntities", int.class).invoke(null, type);
if (entry == null) if (entry == null)
{ {
return currentEntity; return currentEntity;
} }
Class entityClass = (Class)entry.getClass().getDeclaredField("entityClass").get(entry); Class entityClass = (Class)entry.getClass().getDeclaredField("entityClass").get(entry);
Object ret = (Entity)entityClass.getConstructor(World.class, Double.TYPE, Double.TYPE, Double.TYPE).newInstance(world, x, y, z); Object ret = (Entity)entityClass.getConstructor(World.class, Double.TYPE, Double.TYPE, Double.TYPE).newInstance(world, x, y, z);
if (entry.getClass().getDeclaredField("entityHasOwner").getBoolean(entry)) if (entry.getClass().getDeclaredField("entityHasOwner").getBoolean(entry))
{ {
Field owner = entityClass.getField("owner"); Field owner = entityClass.getField("owner");
if (!Entity.class.isAssignableFrom(owner.getType())) if (!Entity.class.isAssignableFrom(owner.getType()))
{ {
throw new Exception(String.format("Entity\'s owner field must be of type Entity, but it is of type %s.", owner.getType())); throw new Exception(String.format("Entity\'s owner field must be of type Entity, but it is of type %s.", owner.getType()));
} }
if (thrower == null) if (thrower == null)
{ {
System.out.println("Received spawn packet for entity with owner, but owner was not found."); System.out.println("Received spawn packet for entity with owner, but owner was not found.");
ModLoader.getLogger().fine("Received spawn packet for entity with owner, but owner was not found."); ModLoader.getLogger().fine("Received spawn packet for entity with owner, but owner was not found.");
} }
else else
{ {
if (!owner.getType().isAssignableFrom(thrower.getClass())) if (!owner.getType().isAssignableFrom(thrower.getClass()))
{ {
throw new Exception(String.format("Tried to assign an entity of type %s to entity owner, which is of type %s.", thrower.getClass(), owner.getType())); throw new Exception(String.format("Tried to assign an entity of type %s to entity owner, which is of type %s.", thrower.getClass(), owner.getType()));
} }
owner.set(ret, thrower); owner.set(ret, thrower);
} }
} }
return ret; return ret;
} }
/** /**
* Attempts to invoke ModLoaderMp.handleGUI if ModLoaderMP is installed. * Attempts to invoke ModLoaderMp.handleGUI if ModLoaderMP is installed.
* If not, it does nothing * If not, it does nothing
* *
* @param pkt The open window packet * @param pkt The open window packet
*/ */
public static void mlmpOpenWindow(Packet100OpenWindow pkt) public static void mlmpOpenWindow(Packet100OpenWindow pkt)
{ {
Class mlmp = getClass("ModLoaderMp"); Class mlmp = getClass("ModLoaderMp");
if (!isMLMPInstalled() || mlmp == null) if (!isMLMPInstalled() || mlmp == null)
{ {
return; return;
} }
try try
{ {
mlmp.getDeclaredMethod("handleGUI", Packet100OpenWindow.class).invoke(null, pkt); mlmp.getDeclaredMethod("handleGUI", Packet100OpenWindow.class).invoke(null, pkt);
} }
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@ -1,49 +1,49 @@
package net.minecraft.src.forge.adaptors; package net.minecraft.src.forge.adaptors;
import net.minecraft.src.Entity; import net.minecraft.src.Entity;
import net.minecraft.src.SoundManager; import net.minecraft.src.SoundManager;
import net.minecraft.src.SoundPoolEntry; import net.minecraft.src.SoundPoolEntry;
import net.minecraft.src.forge.ISoundHandler; import net.minecraft.src.forge.ISoundHandler;
/** /**
* Adaptor class for convince sake when implementing ISoundHandler, as most * Adaptor class for convince sake when implementing ISoundHandler, as most
* mods will only actually care about onSetupAudio/onLoadSoundSettings. * mods will only actually care about onSetupAudio/onLoadSoundSettings.
*/ */
public class SoundHandlerAdaptor implements ISoundHandler public class SoundHandlerAdaptor implements ISoundHandler
{ {
@Override @Override
public void onSetupAudio(SoundManager soundManager){} public void onSetupAudio(SoundManager soundManager){}
@Override @Override
public void onLoadSoundSettings(SoundManager soundManager){} public void onLoadSoundSettings(SoundManager soundManager){}
@Override @Override
public SoundPoolEntry onPlayBackgroundMusic(SoundManager soundManager, SoundPoolEntry entry) public SoundPoolEntry onPlayBackgroundMusic(SoundManager soundManager, SoundPoolEntry entry)
{ {
return entry; return entry;
} }
@Override @Override
public SoundPoolEntry onPlayStreaming(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z) public SoundPoolEntry onPlayStreaming(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z)
{ {
return entry; return entry;
} }
@Override @Override
public SoundPoolEntry onPlaySound(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z, float volume, float pitch) public SoundPoolEntry onPlaySound(SoundManager soundManager, SoundPoolEntry entry, String soundName, float x, float y, float z, float volume, float pitch)
{ {
return entry; return entry;
} }
@Override @Override
public SoundPoolEntry onPlaySoundEffect(SoundManager soundManager, SoundPoolEntry entry, String soundName, float volume, float pitch) public SoundPoolEntry onPlaySoundEffect(SoundManager soundManager, SoundPoolEntry entry, String soundName, float volume, float pitch)
{ {
return entry; return entry;
} }
@Override @Override
public String onPlaySoundAtEntity(Entity entity, String soundName, float volume, float pitch) public String onPlaySoundAtEntity(Entity entity, String soundName, float volume, float pitch)
{ {
return soundName; return soundName;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,20 @@
[ [
{ {
"modid" : "mod_MinecraftForge", "modid" : "mod_MinecraftForge",
"name" : "Minecraft Forge", "name" : "Minecraft Forge",
"version" : "{version}", "version" : "{version}",
"url" : "http://MinecraftForge.net", "url" : "http://MinecraftForge.net",
"credits" : "Lots of people have contributed to MinecraftForge", "credits" : "Lots of people have contributed to MinecraftForge",
"authors": [ "authors": [
"LexManos", "LexManos",
"Eloraam", "Eloraam",
"Spacetoad" "Spacetoad"
], ],
"description": "Minecraft Forge is a common open source API allowing a broad range of mods to work cooperatively together.\nIt allows many mods to be created without them editing the main Minecraft code.", "description": "Minecraft Forge is a common open source API allowing a broad range of mods to work cooperatively together.\nIt allows many mods to be created without them editing the main Minecraft code.",
"logoFile" : "/forge_logo.png", "logoFile" : "/forge_logo.png",
"updateUrl" : "http://minecraftforge.net/forum/index.php/topic,5.0.html", "updateUrl" : "http://minecraftforge.net/forum/index.php/topic,5.0.html",
"parent" : "", "parent" : "",
"screenshots": [ "screenshots": [
] ]
} }
] ]

View File

@ -1,34 +1,34 @@
/** /**
* This software is provided under the terms of the Minecraft Forge Public * This software is provided under the terms of the Minecraft Forge Public
* License v1.0. * License v1.0.
*/ */
package net.minecraft.src.forge; package net.minecraft.src.forge;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import net.minecraft.src.Achievement; import net.minecraft.src.Achievement;
public class AchievementPage public class AchievementPage
{ {
private String name; private String name;
private LinkedList<Achievement> achievements; private LinkedList<Achievement> achievements;
public AchievementPage(String name, Achievement... achievements) public AchievementPage(String name, Achievement... achievements)
{ {
this.name = name; this.name = name;
this.achievements = new LinkedList<Achievement>(Arrays.asList(achievements)); this.achievements = new LinkedList<Achievement>(Arrays.asList(achievements));
} }
public String getName() public String getName()
{ {
return name; return name;
} }
public List<Achievement> getAchievements() public List<Achievement> getAchievements()
{ {
return achievements; return achievements;
} }
} }

View File

@ -1,76 +1,76 @@
package net.minecraft.src.forge; package net.minecraft.src.forge;
import net.minecraft.src.EntityPlayer; import net.minecraft.src.EntityPlayer;
public interface IChatHandler public interface IChatHandler
{ {
/** /**
* Called when a player sends a normal chat message to the server, * Called when a player sends a normal chat message to the server,
* you can manipulate the message parameter by returning a modified * you can manipulate the message parameter by returning a modified
* version from this function. * version from this function.
* *
* This is only called on the server side. * This is only called on the server side.
* *
* @param player The player issuing the message * @param player The player issuing the message
* @param message The message the player is sending * @param message The message the player is sending
* @return The message to be displayed, normal case is the 'message' parameter. Return null to cancel displaying this message. * @return The message to be displayed, normal case is the 'message' parameter. Return null to cancel displaying this message.
*/ */
public String onServerChat(EntityPlayer player, String message); public String onServerChat(EntityPlayer player, String message);
/** /**
* Called when a player sends a normal chat message to the server * Called when a player sends a normal chat message to the server
* that starts with a '/'. * that starts with a '/'.
* *
* This is only called on the server side. * This is only called on the server side.
* *
* Return true from this function to indicate that you have * Return true from this function to indicate that you have
* handled the command and no further processing is necessary. * handled the command and no further processing is necessary.
* *
* @param player The player trying to issue the command * @param player The player trying to issue the command
* @param isOp True if the player is on the Op list * @param isOp True if the player is on the Op list
* @param command The command trying to be issued * @param command The command trying to be issued
* @return True if no further processing is necessary, false to continue processing. * @return True if no further processing is necessary, false to continue processing.
*/ */
public boolean onChatCommand(EntityPlayer player, boolean isOp, String command); public boolean onChatCommand(EntityPlayer player, boolean isOp, String command);
/** /**
* Called when either the console or a player issues a / command that is not handled elsewhere. * Called when either the console or a player issues a / command that is not handled elsewhere.
* *
* This is only called on the server side. * This is only called on the server side.
* *
* Return true from this function to indicate that you have * Return true from this function to indicate that you have
* handled the command and no further processing is necessary. * handled the command and no further processing is necessary.
* *
* The listener will always be a instance of ICommandListener, but because the client does * The listener will always be a instance of ICommandListener, but because the client does
* not have this class it is defined as a Object to allow client compilation. * not have this class it is defined as a Object to allow client compilation.
* *
* @param listener The source of the command, will always be a instance of ICommandListener * @param listener The source of the command, will always be a instance of ICommandListener
* @param username The username of the person issuing the command, 'CONSOLE' if it's not a player. * @param username The username of the person issuing the command, 'CONSOLE' if it's not a player.
* @param command The command trying to be issued * @param command The command trying to be issued
* @return True if no further processing is necessary, false to continue processing. * @return True if no further processing is necessary, false to continue processing.
*/ */
public boolean onServerCommand(Object listener, String username, String command); public boolean onServerCommand(Object listener, String username, String command);
/** /**
* *
* Called when either the console or a player issues the /say command * Called when either the console or a player issues the /say command
* *
* This is only called on the server side. * This is only called on the server side.
* *
* @param listener The source of the command, will always be a instance of ICommandListener * @param listener The source of the command, will always be a instance of ICommandListener
* @param username The username of the person issuing the command, 'CONSOLE' if it's not a player. * @param username The username of the person issuing the command, 'CONSOLE' if it's not a player.
* @param message The message trying to be sent, without the /say * @param message The message trying to be sent, without the /say
* @return The message to be displayed, normal case is the 'message' parameter. Return null to cancel displaying this message. * @return The message to be displayed, normal case is the 'message' parameter. Return null to cancel displaying this message.
*/ */
public String onServerCommandSay(Object listener, String username, String message); public String onServerCommandSay(Object listener, String username, String message);
/** /**
* Called when the client receives a Chat packet. * Called when the client receives a Chat packet.
* *
* This is only called on the client side * This is only called on the client side
* *
* @param message The chat message received * @param message The chat message received
* @return The message to be displayed, normal case is the 'message' parameter. Return null to cancel displaying this message. * @return The message to be displayed, normal case is the 'message' parameter. Return null to cancel displaying this message.
*/ */
public String onClientChatRecv(String message); public String onClientChatRecv(String message);
} }

View File

@ -1,24 +1,24 @@
/** /**
* This software is provided under the terms of the Minecraft Forge Public * This software is provided under the terms of the Minecraft Forge Public
* License v1.0. * License v1.0.
*/ */
package net.minecraft.src.forge; package net.minecraft.src.forge;
import net.minecraft.src.EntityPlayer; import net.minecraft.src.EntityPlayer;
import net.minecraft.src.Entity; import net.minecraft.src.Entity;
public interface IEntityInteractHandler public interface IEntityInteractHandler
{ {
/** /**
* This is called before a player attacks, or interacts {left or right click by default} * This is called before a player attacks, or interacts {left or right click by default}
* with another entity. Before any damage, or other interaction code is run. * with another entity. Before any damage, or other interaction code is run.
* In multiplayer, this is called by both the client and the server. * In multiplayer, this is called by both the client and the server.
* *
* @param player The player doing the interacting * @param player The player doing the interacting
* @param entity The entity being interacted with * @param entity The entity being interacted with
* @param isAttack True if it is a attack {left click} false if it is a interact {right click} * @param isAttack True if it is a attack {left click} false if it is a interact {right click}
* @return True to continue processing, false to cancel. * @return True to continue processing, false to cancel.
*/ */
public boolean onEntityInteract(EntityPlayer player, Entity entity, boolean isAttack); public boolean onEntityInteract(EntityPlayer player, Entity entity, boolean isAttack);
} }

View File

@ -1,127 +1,127 @@
/** /**
* This software is provided under the terms of the Minecraft Forge Public * This software is provided under the terms of the Minecraft Forge Public
* License v1.0. * License v1.0.
*/ */
package net.minecraft.src.forge; package net.minecraft.src.forge;
import java.util.ArrayList; import java.util.ArrayList;
import net.minecraft.src.EntityItem; import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityLiving; import net.minecraft.src.EntityLiving;
import net.minecraft.src.DamageSource; import net.minecraft.src.DamageSource;
import net.minecraft.src.World; import net.minecraft.src.World;
public interface IEntityLivingHandler public interface IEntityLivingHandler
{ {
/** /**
* Raised when an EntityLiving is spawned into the world from natural means, meaning * Raised when an EntityLiving is spawned into the world from natural means, meaning
* not by command, MobSpawner, cheat, etc.. Just naturally throughout the world. * not by command, MobSpawner, cheat, etc.. Just naturally throughout the world.
* *
* This allows the mod to create special functionality that runs on a mob natural * This allows the mod to create special functionality that runs on a mob natural
* spawn. The Vanilla minecraft mechanic of having 'Spider Jockies', the color of * spawn. The Vanilla minecraft mechanic of having 'Spider Jockies', the color of
* sheep's wool, and Ocelot's spawning with babies can be canceled by returning * sheep's wool, and Ocelot's spawning with babies can be canceled by returning
* true from this function * true from this function
* *
* Returning true will indicate that you have performed your special spawning, * Returning true will indicate that you have performed your special spawning,
* and no more handling will be done. * and no more handling will be done.
* *
* @param entity The newly spawned entity * @param entity The newly spawned entity
* @param world The world the entity is in * @param world The world the entity is in
* @param x The Entitie's X Position * @param x The Entitie's X Position
* @param y The Entitie's Y Position * @param y The Entitie's Y Position
* @param z The Entitie's Z Position * @param z The Entitie's Z Position
* @return True if the event was handled and no more processing should be done, false to continue processing * @return True if the event was handled and no more processing should be done, false to continue processing
*/ */
public boolean onEntityLivingSpawn(EntityLiving entity, World world, float x, float y, float z); public boolean onEntityLivingSpawn(EntityLiving entity, World world, float x, float y, float z);
/** /**
* This is called when any EntityLiving's health reaches 0. * This is called when any EntityLiving's health reaches 0.
* You can cancel the death here, but you must raise the health or it will die again. * You can cancel the death here, but you must raise the health or it will die again.
* In multiplayer, this is called by both the client and the server. * In multiplayer, this is called by both the client and the server.
* *
* @param entity Entity about to die * @param entity Entity about to die
* @param killer DamageSource instance causing the death * @param killer DamageSource instance causing the death
* @return True to continue processing, false to cancel. * @return True to continue processing, false to cancel.
*/ */
public boolean onEntityLivingDeath(EntityLiving entity, DamageSource killer); public boolean onEntityLivingDeath(EntityLiving entity, DamageSource killer);
/** /**
* This is called immediately after an EntityLiving receives a new attack target from AI classes. * This is called immediately after an EntityLiving receives a new attack target from AI classes.
* eg when a Zombie 'spots' a player. Handles friendly fire (setRevengeTarget) as well. * eg when a Zombie 'spots' a player. Handles friendly fire (setRevengeTarget) as well.
* In multiplayer, this is called by the server only. * In multiplayer, this is called by the server only.
* *
* @param entity Entity attacking * @param entity Entity attacking
* @param target Entity designated as new target * @param target Entity designated as new target
*/ */
public void onEntityLivingSetAttackTarget(EntityLiving entity, EntityLiving target); public void onEntityLivingSetAttackTarget(EntityLiving entity, EntityLiving target);
/** /**
* This is called when any EntityLiving takes damage from any DamageSource. * This is called when any EntityLiving takes damage from any DamageSource.
* In multiplayer, this is called by both the client and the server. * In multiplayer, this is called by both the client and the server.
* *
* @param entity Entity being attacked * @param entity Entity being attacked
* @param attack DamageSource instance of the attack * @param attack DamageSource instance of the attack
* @param damage Unmitigated damage the attack would cause * @param damage Unmitigated damage the attack would cause
* @return True if the event was handled and no more processing should be done, false to continue processing * @return True if the event was handled and no more processing should be done, false to continue processing
*/ */
public boolean onEntityLivingAttacked(EntityLiving entity, DamageSource attack, int damage); public boolean onEntityLivingAttacked(EntityLiving entity, DamageSource attack, int damage);
/** /**
* This is called immediately after an EntityLiving started a jump * This is called immediately after an EntityLiving started a jump
* Velocity will already be set and can be modified. * Velocity will already be set and can be modified.
* *
* @param entity Entity starting the jump * @param entity Entity starting the jump
*/ */
public void onEntityLivingJump(EntityLiving entity); public void onEntityLivingJump(EntityLiving entity);
/** /**
* This is called when an EntityLiving reconnects with the ground. * This is called when an EntityLiving reconnects with the ground.
* Aborting this would stop both damage and the landing sound. * Aborting this would stop both damage and the landing sound.
* *
* @param entity Entity which fell * @param entity Entity which fell
* @param distance absolute height between the last position touching the ground and the current. * @param distance absolute height between the last position touching the ground and the current.
* @return True if the event was handled and no more processing should be done, false to continue processing * @return True if the event was handled and no more processing should be done, false to continue processing
*/ */
public boolean onEntityLivingFall(EntityLiving entity, float distance); public boolean onEntityLivingFall(EntityLiving entity, float distance);
/** /**
* This is called before EntityLiving's Base Update Tick. * This is called before EntityLiving's Base Update Tick.
* Aborting this process will freeze both Movement and Actions. * Aborting this process will freeze both Movement and Actions.
* *
* @param entity Entity being ticked * @param entity Entity being ticked
* @return True if the event was handled and no more processing should be done, false to continue processing * @return True if the event was handled and no more processing should be done, false to continue processing
*/ */
public boolean onEntityLivingUpdate(EntityLiving entity); public boolean onEntityLivingUpdate(EntityLiving entity);
/** /**
* This is called whenever a EntityLiving is hurt, before any armor calculations are taken into effect. * This is called whenever a EntityLiving is hurt, before any armor calculations are taken into effect.
* Before any blocking, or potions are taken into account. * Before any blocking, or potions are taken into account.
* Returning 0 from this will stop all processing. * Returning 0 from this will stop all processing.
* For the client's entity, this is only called in Single player, or if you are the server. * For the client's entity, this is only called in Single player, or if you are the server.
* *
* @param entity The entity being hurt * @param entity The entity being hurt
* @param source The type of damage being dealt * @param source The type of damage being dealt
* @param damage The amount of damage being dealt * @param damage The amount of damage being dealt
* @return The amount of damage to let through. Returning 0 will prevent any further processing. * @return The amount of damage to let through. Returning 0 will prevent any further processing.
*/ */
public int onEntityLivingHurt(EntityLiving entity, DamageSource source, int damage); public int onEntityLivingHurt(EntityLiving entity, DamageSource source, int damage);
/** /**
* This is called after a EntityLiving die, and it spawns it's loot. The drop list should contain any item that the entity spawned at death. * This is called after a EntityLiving die, and it spawns it's loot. The drop list should contain any item that the entity spawned at death.
* May not work properly on all Mod entities if they do not use dropFewItems/dropRareDrop/entityDropItem * May not work properly on all Mod entities if they do not use dropFewItems/dropRareDrop/entityDropItem
* This will not contain the special record that creepers drop when they are killed by a Skeleton, or the apple notch drops. * This will not contain the special record that creepers drop when they are killed by a Skeleton, or the apple notch drops.
* Or the player's inventory. * Or the player's inventory.
* *
* If you need to deal with the Player's inventory, do so in onEntityLivingDeath * If you need to deal with the Player's inventory, do so in onEntityLivingDeath
* In most cases, drops will be empty if the entity was a baby that hadn't reached full size yet. * In most cases, drops will be empty if the entity was a baby that hadn't reached full size yet.
* *
* @param entity The entity that is droping the items * @param entity The entity that is droping the items
* @param source The damage source that caused the entities death * @param source The damage source that caused the entities death
* @param drops An ArrayList containing all items to drop, AYou must make sure to not cause any concurancy exceptions with this * @param drops An ArrayList containing all items to drop, AYou must make sure to not cause any concurancy exceptions with this
* @param lootingLevel The Looting enchantment level if the attacker was a player and they had the enchantment, else 0 * @param lootingLevel The Looting enchantment level if the attacker was a player and they had the enchantment, else 0
* @param recentlyHit Signifying if the entity was recently hit by a player. * @param recentlyHit Signifying if the entity was recently hit by a player.
* @param specialDropValue Random number used to determine if the 'special' loot should be dropped. 0 if the entity was a child * @param specialDropValue Random number used to determine if the 'special' loot should be dropped. 0 if the entity was a child
*/ */
public void onEntityLivingDrops(EntityLiving entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue); public void onEntityLivingDrops(EntityLiving entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue);
} }

View File

@ -1,16 +1,16 @@
/** /**
* This software is provided under the terms of the Minecraft Forge Public * This software is provided under the terms of the Minecraft Forge Public
* License v1.0. * License v1.0.
*/ */
package net.minecraft.src.forge; package net.minecraft.src.forge;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
public interface IFuelHandler public interface IFuelHandler
{ {
/** Called when a furnace gains fuel to get its burn time. /** Called when a furnace gains fuel to get its burn time.
* @return fuel burn time in ticks or 0 to continue processing * @return fuel burn time in ticks or 0 to continue processing
*/ */
public int getItemBurnTime(ItemStack stack); public int getItemBurnTime(ItemStack stack);
} }

View File

@ -1,50 +1,50 @@
package net.minecraft.src.forge; package net.minecraft.src.forge;
import net.minecraft.src.Chunk; import net.minecraft.src.Chunk;
import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.World; import net.minecraft.src.World;
public interface ISaveEventHandler public interface ISaveEventHandler
{ {
/** /**
* Called when the world is created, either newly created or loaded from a save file * Called when the world is created, either newly created or loaded from a save file
* @param world The world being loaded. * @param world The world being loaded.
*/ */
public void onWorldLoad(World world); public void onWorldLoad(World world);
/** /**
* Called whenever the world is saving. Use this to save extra data alongside the world, eg. maps. * Called whenever the world is saving. Use this to save extra data alongside the world, eg. maps.
* @param world The world being saved. * @param world The world being saved.
*/ */
public void onWorldSave(World world); public void onWorldSave(World world);
/** /**
* Called when a chunk is created, either newly generated or loaded from a save file * Called when a chunk is created, either newly generated or loaded from a save file
* @param world The world containing this chunk. * @param world The world containing this chunk.
* @param chunk The chunk being loaded. * @param chunk The chunk being loaded.
*/ */
public void onChunkLoad(World world, Chunk chunk); public void onChunkLoad(World world, Chunk chunk);
/** /**
* Called when a chunk is unloaded and removed from the world * Called when a chunk is unloaded and removed from the world
* @param world The world containing this chunk. * @param world The world containing this chunk.
* @param chunk The chunk being loaded. * @param chunk The chunk being loaded.
*/ */
public void onChunkUnload(World world, Chunk chunk); public void onChunkUnload(World world, Chunk chunk);
/** /**
* Use this to save extra data in with the chunk file. * Use this to save extra data in with the chunk file.
* @param world The world containing this chunk. * @param world The world containing this chunk.
* @param chunk The chunk being saved. * @param chunk The chunk being saved.
* @param data The compound to save data into and be written to disk * @param data The compound to save data into and be written to disk
*/ */
public void onChunkSaveData(World world, Chunk chunk, NBTTagCompound data); public void onChunkSaveData(World world, Chunk chunk, NBTTagCompound data);
/** /**
* Use this to load extra save data from a chunk file. * Use this to load extra save data from a chunk file.
* @param world The world containing this chunk. * @param world The world containing this chunk.
* @param chunk The chunk being loaded. * @param chunk The chunk being loaded.
* @param data The compound to load data from * @param data The compound to load data from
*/ */
public void onChunkLoadData(World world, Chunk chunk, NBTTagCompound data); public void onChunkLoadData(World world, Chunk chunk, NBTTagCompound data);
} }

View File

@ -1,29 +1,29 @@
package net.minecraft.src.forge; package net.minecraft.src.forge;
import net.minecraft.src.EntityLiving; import net.minecraft.src.EntityLiving;
import net.minecraft.src.World; import net.minecraft.src.World;
@Deprecated //See IEntityLivingHandler @Deprecated //See IEntityLivingHandler
public interface ISpecialMobSpawnHandler public interface ISpecialMobSpawnHandler
{ {
/** /**
* Raised when a Entity is spawned into the world from natural means, meaning * Raised when a Entity is spawned into the world from natural means, meaning
* not by command, MobSpawner, cheat, etc.. Just naturally throughout the world. * not by command, MobSpawner, cheat, etc.. Just naturally throughout the world.
* *
* This allows the mod to create special functionality that runs on a mob natural * This allows the mod to create special functionality that runs on a mob natural
* spawn. The Vanilla minecraft mechanic of having 'Spider Jockies', the color of * spawn. The Vanilla minecraft mechanic of having 'Spider Jockies', the color of
* sheep's wool, and Ocelot's spawning with babies can be canceled by returning * sheep's wool, and Ocelot's spawning with babies can be canceled by returning
* true from this function * true from this function
* *
* Returning true will indicate that you have performed your special spawning, * Returning true will indicate that you have performed your special spawning,
* and no more handling will be done. * and no more handling will be done.
* *
* @param entity The newly spawned entity * @param entity The newly spawned entity
* @param world The world the entity is in * @param world The world the entity is in
* @param x The Entitie's X Position * @param x The Entitie's X Position
* @param y The Entitie's Y Position * @param y The Entitie's Y Position
* @param z The Entitie's Z Position * @param z The Entitie's Z Position
* @return True to prevent any further special case handling from executing. * @return True to prevent any further special case handling from executing.
*/ */
public boolean onSpecialEntitySpawn(EntityLiving entity, World world, float x, float y, float z); public boolean onSpecialEntitySpawn(EntityLiving entity, World world, float x, float y, float z);
} }

View File

@ -1,64 +1,64 @@
package net.minecraft.src.forge.adaptors; package net.minecraft.src.forge.adaptors;
import java.util.ArrayList; import java.util.ArrayList;
import net.minecraft.src.DamageSource; import net.minecraft.src.DamageSource;
import net.minecraft.src.EntityItem; import net.minecraft.src.EntityItem;
import net.minecraft.src.EntityLiving; import net.minecraft.src.EntityLiving;
import net.minecraft.src.World; import net.minecraft.src.World;
import net.minecraft.src.forge.IEntityLivingHandler; import net.minecraft.src.forge.IEntityLivingHandler;
public class EntityLivingHandlerAdaptor implements IEntityLivingHandler public class EntityLivingHandlerAdaptor implements IEntityLivingHandler
{ {
@Override @Override
public boolean onEntityLivingSpawn(EntityLiving entity, World world, float x, float y, float z) public boolean onEntityLivingSpawn(EntityLiving entity, World world, float x, float y, float z)
{ {
return false; return false;
} }
@Override @Override
public boolean onEntityLivingDeath(EntityLiving entity, DamageSource killer) public boolean onEntityLivingDeath(EntityLiving entity, DamageSource killer)
{ {
return false; return false;
} }
@Override @Override
public void onEntityLivingSetAttackTarget(EntityLiving entity, EntityLiving target) public void onEntityLivingSetAttackTarget(EntityLiving entity, EntityLiving target)
{ {
} }
@Override @Override
public boolean onEntityLivingAttacked(EntityLiving entity, DamageSource attack, int damage) public boolean onEntityLivingAttacked(EntityLiving entity, DamageSource attack, int damage)
{ {
return false; return false;
} }
@Override @Override
public void onEntityLivingJump(EntityLiving entity) public void onEntityLivingJump(EntityLiving entity)
{ {
} }
@Override @Override
public boolean onEntityLivingFall(EntityLiving entity, float distance) public boolean onEntityLivingFall(EntityLiving entity, float distance)
{ {
return false; return false;
} }
@Override @Override
public boolean onEntityLivingUpdate(EntityLiving entity) public boolean onEntityLivingUpdate(EntityLiving entity)
{ {
return false; return false;
} }
@Override @Override
public int onEntityLivingHurt(EntityLiving entity, DamageSource source, int damage) public int onEntityLivingHurt(EntityLiving entity, DamageSource source, int damage)
{ {
return damage; return damage;
} }
@Override @Override
public void onEntityLivingDrops(EntityLiving entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue) public void onEntityLivingDrops(EntityLiving entity, DamageSource source, ArrayList<EntityItem> drops, int lootingLevel, boolean recentlyHit, int specialDropValue)
{ {
} }
} }

View File

@ -1,138 +1,138 @@
package net.minecraft.src.forge.oredict; package net.minecraft.src.forge.oredict;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import net.minecraft.src.Block; import net.minecraft.src.Block;
import net.minecraft.src.Item; import net.minecraft.src.Item;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
import net.minecraft.src.forge.IOreHandler; import net.minecraft.src.forge.IOreHandler;
public class OreDictionary public class OreDictionary
{ {
private static int maxID = 0; private static int maxID = 0;
private static HashMap<String, Integer> oreIDs = new HashMap<String, Integer>(); private static HashMap<String, Integer> oreIDs = new HashMap<String, Integer>();
private static HashMap<Integer, ArrayList<ItemStack>> oreStacks = new HashMap<Integer, ArrayList<ItemStack>>(); private static HashMap<Integer, ArrayList<ItemStack>> oreStacks = new HashMap<Integer, ArrayList<ItemStack>>();
private static ArrayList<IOreHandler> oreHandlers = new ArrayList<IOreHandler>(); private static ArrayList<IOreHandler> oreHandlers = new ArrayList<IOreHandler>();
/** /**
* Gets the integer ID for the specified ore name. * Gets the integer ID for the specified ore name.
* If the name does not have a ID it assigns it a new one. * If the name does not have a ID it assigns it a new one.
* *
* @param name The unique name for this ore 'oreIron', 'ingotIron', etc.. * @param name The unique name for this ore 'oreIron', 'ingotIron', etc..
* @return A number representing the ID for this ore type * @return A number representing the ID for this ore type
*/ */
public static int getOreID(String name) public static int getOreID(String name)
{ {
Integer val = oreIDs.get(name); Integer val = oreIDs.get(name);
if (val == null) if (val == null)
{ {
val = maxID++; val = maxID++;
oreIDs.put(name, val); oreIDs.put(name, val);
oreStacks.put(val, new ArrayList<ItemStack>()); oreStacks.put(val, new ArrayList<ItemStack>());
} }
return val; return val;
} }
/** /**
* Reverse of getOreID, will not create new entries. * Reverse of getOreID, will not create new entries.
* *
* @param id The ID to translate to a string * @param id The ID to translate to a string
* @return The String name, or "Unknown" if not found. * @return The String name, or "Unknown" if not found.
*/ */
public static String getOreName(int id) public static String getOreName(int id)
{ {
for (Map.Entry<String, Integer> entry : oreIDs.entrySet()) for (Map.Entry<String, Integer> entry : oreIDs.entrySet())
{ {
if (id == entry.getValue()) if (id == entry.getValue())
{ {
return entry.getKey(); return entry.getKey();
} }
} }
return "Unknown"; return "Unknown";
} }
/** /**
* Retrieves the ArrayList of items that are registered to this ore type. * Retrieves the ArrayList of items that are registered to this ore type.
* Creates the list as empty if it did not exist. * Creates the list as empty if it did not exist.
* *
* @param id The ore ID, see getOreID * @param id The ore ID, see getOreID
* @return An arrayList containing ItemStacks registered for this ore * @return An arrayList containing ItemStacks registered for this ore
*/ */
public static ArrayList<ItemStack> getOres(String name) public static ArrayList<ItemStack> getOres(String name)
{ {
return getOres(getOreID(name)); return getOres(getOreID(name));
} }
/** /**
* Retrieves the ArrayList of items that are registered to this ore type. * Retrieves the ArrayList of items that are registered to this ore type.
* Creates the list as empty if it did not exist. * Creates the list as empty if it did not exist.
* *
* @param id The ore ID, see getOreID * @param id The ore ID, see getOreID
* @return An arrayList containing ItemStacks registered for this ore * @return An arrayList containing ItemStacks registered for this ore
*/ */
public static ArrayList<ItemStack> getOres(Integer id) public static ArrayList<ItemStack> getOres(Integer id)
{ {
ArrayList<ItemStack> val = oreStacks.get(id); ArrayList<ItemStack> val = oreStacks.get(id);
if (val == null) if (val == null)
{ {
val = new ArrayList<ItemStack>(); val = new ArrayList<ItemStack>();
oreStacks.put(id, val); oreStacks.put(id, val);
} }
return val; return val;
} }
/** /**
* Register a new ore handler. * Register a new ore handler.
* This will automatically call the handler with all current ores during * This will automatically call the handler with all current ores during
* registration, and every time a new ore is added later. * registration, and every time a new ore is added later.
* *
* @param handler The Ore Handler * @param handler The Ore Handler
*/ */
public static void registerOreHandler(IOreHandler handler) public static void registerOreHandler(IOreHandler handler)
{ {
oreHandlers.add(handler); oreHandlers.add(handler);
HashMap<String, Integer> tmp = (HashMap<String, Integer>)oreIDs.clone(); HashMap<String, Integer> tmp = (HashMap<String, Integer>)oreIDs.clone();
for(Map.Entry<String, Integer> entry : tmp.entrySet()) for(Map.Entry<String, Integer> entry : tmp.entrySet())
{ {
for(ItemStack stack : getOres(entry.getValue())) for(ItemStack stack : getOres(entry.getValue()))
{ {
handler.registerOre(entry.getKey(), stack); handler.registerOre(entry.getKey(), stack);
} }
} }
} }
//Convenience functions that make for cleaner code mod side. They all drill down to registerOre(String, int, ItemStack) //Convenience functions that make for cleaner code mod side. They all drill down to registerOre(String, int, ItemStack)
public static void registerOre(String name, Item ore){ registerOre(name, new ItemStack(ore)); } public static void registerOre(String name, Item ore){ registerOre(name, new ItemStack(ore)); }
public static void registerOre(String name, Block ore){ registerOre(name, new ItemStack(ore)); } public static void registerOre(String name, Block ore){ registerOre(name, new ItemStack(ore)); }
public static void registerOre(String name, ItemStack ore){ registerOre(name, getOreID(name), ore); } public static void registerOre(String name, ItemStack ore){ registerOre(name, getOreID(name), ore); }
public static void registerOre(int id, Item ore){ registerOre(id, new ItemStack(ore)); } public static void registerOre(int id, Item ore){ registerOre(id, new ItemStack(ore)); }
public static void registerOre(int id, Block ore){ registerOre(id, new ItemStack(ore)); } public static void registerOre(int id, Block ore){ registerOre(id, new ItemStack(ore)); }
public static void registerOre(int id, ItemStack ore){ registerOre(getOreName(id), id, ore); } public static void registerOre(int id, ItemStack ore){ registerOre(getOreName(id), id, ore); }
/** /**
* Registers a ore item into the dictionary. * Registers a ore item into the dictionary.
* Raises the registerOre function in all registered handlers. * Raises the registerOre function in all registered handlers.
* *
* @param name The name of the ore * @param name The name of the ore
* @param id The ID of the ore * @param id The ID of the ore
* @param ore The ore's ItemStack * @param ore The ore's ItemStack
*/ */
private static void registerOre(String name, int id, ItemStack ore) private static void registerOre(String name, int id, ItemStack ore)
{ {
ArrayList<ItemStack> ores = getOres(id); ArrayList<ItemStack> ores = getOres(id);
ore = ore.copy(); ore = ore.copy();
ores.add(ore); ores.add(ore);
for (IOreHandler handler : oreHandlers) for (IOreHandler handler : oreHandlers)
{ {
handler.registerOre(name, ore); handler.registerOre(name, ore);
} }
} }
} }

View File

@ -1,216 +1,216 @@
package net.minecraft.src.forge.oredict; package net.minecraft.src.forge.oredict;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import net.minecraft.src.Block; import net.minecraft.src.Block;
import net.minecraft.src.IRecipe; import net.minecraft.src.IRecipe;
import net.minecraft.src.InventoryCrafting; import net.minecraft.src.InventoryCrafting;
import net.minecraft.src.Item; import net.minecraft.src.Item;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
import net.minecraft.src.ShapedRecipes; import net.minecraft.src.ShapedRecipes;
public class ShapedOreRecipe implements IRecipe public class ShapedOreRecipe implements IRecipe
{ {
//Added in for future ease of change, but hard coded for now. //Added in for future ease of change, but hard coded for now.
private static final int MAX_CRAFT_GRID_WIDTH = 3; private static final int MAX_CRAFT_GRID_WIDTH = 3;
private static final int MAX_CRAFT_GRID_HEIGHT = 3; private static final int MAX_CRAFT_GRID_HEIGHT = 3;
private ItemStack output = null; private ItemStack output = null;
private Object[] input = null; private Object[] input = null;
private int width = 0; private int width = 0;
private int height = 0; private int height = 0;
private boolean mirriored = true; private boolean mirriored = true;
public ShapedOreRecipe(Block result, Object... recipe){ this(result, true, recipe);} public ShapedOreRecipe(Block result, Object... recipe){ this(result, true, recipe);}
public ShapedOreRecipe(Item result, Object... recipe){ this(result, true, recipe); } public ShapedOreRecipe(Item result, Object... recipe){ this(result, true, recipe); }
public ShapedOreRecipe(ItemStack result, Object... recipe){ this(result, true, recipe); } public ShapedOreRecipe(ItemStack result, Object... recipe){ this(result, true, recipe); }
public ShapedOreRecipe(Block result, boolean mirrior, Object... recipe){ this(new ItemStack(result), mirrior, recipe);} public ShapedOreRecipe(Block result, boolean mirrior, Object... recipe){ this(new ItemStack(result), mirrior, recipe);}
public ShapedOreRecipe(Item result, boolean mirrior, Object... recipe){ this(new ItemStack(result), mirrior, recipe); } public ShapedOreRecipe(Item result, boolean mirrior, Object... recipe){ this(new ItemStack(result), mirrior, recipe); }
public ShapedOreRecipe(ItemStack result, boolean mirrior, Object... recipe) public ShapedOreRecipe(ItemStack result, boolean mirrior, Object... recipe)
{ {
output = result.copy(); output = result.copy();
mirriored = mirrior; mirriored = mirrior;
String shape = ""; String shape = "";
int idx = 0; int idx = 0;
if (recipe[idx] instanceof String[]) if (recipe[idx] instanceof String[])
{ {
String[] parts = ((String[])recipe[idx++]); String[] parts = ((String[])recipe[idx++]);
for (String s : parts) for (String s : parts)
{ {
width = s.length(); width = s.length();
shape += s; shape += s;
} }
height = parts.length; height = parts.length;
} }
else else
{ {
while (recipe[idx] instanceof String) while (recipe[idx] instanceof String)
{ {
String s = (String)recipe[idx++]; String s = (String)recipe[idx++];
shape += s; shape += s;
width = s.length(); width = s.length();
height++; height++;
} }
} }
if (width * height != shape.length()) if (width * height != shape.length())
{ {
String ret = "Invalid shaped ore recipe: "; String ret = "Invalid shaped ore recipe: ";
for (Object tmp : recipe) for (Object tmp : recipe)
{ {
ret += tmp + ", "; ret += tmp + ", ";
} }
ret += output; ret += output;
throw new RuntimeException(ret); throw new RuntimeException(ret);
} }
HashMap<Character, Object> itemMap = new HashMap<Character, Object>(); HashMap<Character, Object> itemMap = new HashMap<Character, Object>();
for (; idx < recipe.length; idx += 2) for (; idx < recipe.length; idx += 2)
{ {
Character chr = (Character)recipe[idx]; Character chr = (Character)recipe[idx];
Object in = recipe[idx + 1]; Object in = recipe[idx + 1];
Object val = null; Object val = null;
if (in instanceof ItemStack) if (in instanceof ItemStack)
{ {
itemMap.put(chr, ((ItemStack)in).copy()); itemMap.put(chr, ((ItemStack)in).copy());
} }
else if (in instanceof Item) else if (in instanceof Item)
{ {
itemMap.put(chr, new ItemStack((Item)in)); itemMap.put(chr, new ItemStack((Item)in));
} }
else if (in instanceof Block) else if (in instanceof Block)
{ {
itemMap.put(chr, new ItemStack((Block)in, 1, -1)); itemMap.put(chr, new ItemStack((Block)in, 1, -1));
} }
else if (in instanceof String) else if (in instanceof String)
{ {
itemMap.put(chr, OreDictionary.getOres((String)in)); itemMap.put(chr, OreDictionary.getOres((String)in));
} }
else else
{ {
String ret = "Invalid shaped ore recipe: "; String ret = "Invalid shaped ore recipe: ";
for (Object tmp : recipe) for (Object tmp : recipe)
{ {
ret += tmp + ", "; ret += tmp + ", ";
} }
ret += output; ret += output;
throw new RuntimeException(ret); throw new RuntimeException(ret);
} }
} }
input = new Object[width * height]; input = new Object[width * height];
int x = 0; int x = 0;
for (char chr : shape.toCharArray()) for (char chr : shape.toCharArray())
{ {
input[x++] = itemMap.get(chr); input[x++] = itemMap.get(chr);
} }
} }
@Override @Override
public ItemStack getCraftingResult(InventoryCrafting var1){ return output.copy(); } public ItemStack getCraftingResult(InventoryCrafting var1){ return output.copy(); }
@Override @Override
public int getRecipeSize(){ return input.length; } public int getRecipeSize(){ return input.length; }
@Override @Override
public ItemStack getRecipeOutput(){ return output; } public ItemStack getRecipeOutput(){ return output; }
@Override @Override
public boolean matches(InventoryCrafting inv) public boolean matches(InventoryCrafting inv)
{ {
for (int x = 0; x <= MAX_CRAFT_GRID_WIDTH - width; x++) for (int x = 0; x <= MAX_CRAFT_GRID_WIDTH - width; x++)
{ {
for (int y = 0; y <= MAX_CRAFT_GRID_HEIGHT - height; ++y) for (int y = 0; y <= MAX_CRAFT_GRID_HEIGHT - height; ++y)
{ {
if (checkMatch(inv, x, y, true)) if (checkMatch(inv, x, y, true))
{ {
return true; return true;
} }
if (mirriored && checkMatch(inv, x, y, false)) if (mirriored && checkMatch(inv, x, y, false))
{ {
return true; return true;
} }
} }
} }
return false; return false;
} }
private boolean checkMatch(InventoryCrafting inv, int startX, int startY, boolean mirrior) private boolean checkMatch(InventoryCrafting inv, int startX, int startY, boolean mirrior)
{ {
for (int x = 0; x < MAX_CRAFT_GRID_WIDTH; x++) for (int x = 0; x < MAX_CRAFT_GRID_WIDTH; x++)
{ {
for (int y = 0; y < MAX_CRAFT_GRID_HEIGHT; y++) for (int y = 0; y < MAX_CRAFT_GRID_HEIGHT; y++)
{ {
int subX = x - startX; int subX = x - startX;
int subY = y - startY; int subY = y - startY;
Object target = null; Object target = null;
if (subX >= 0 && subY >= 0 && subX < width && subY < height) if (subX >= 0 && subY >= 0 && subX < width && subY < height)
{ {
if (mirrior) if (mirrior)
{ {
target = input[width - subX - 1 + subY * width]; target = input[width - subX - 1 + subY * width];
} }
else else
{ {
target = input[subX + subY * width]; target = input[subX + subY * width];
} }
} }
ItemStack slot = inv.getStackInRowAndColumn(x, y); ItemStack slot = inv.getStackInRowAndColumn(x, y);
if (target instanceof ItemStack) if (target instanceof ItemStack)
{ {
if (!checkItemEquals((ItemStack)target, slot)) if (!checkItemEquals((ItemStack)target, slot))
{ {
return false; return false;
} }
} }
else if (target instanceof ArrayList) else if (target instanceof ArrayList)
{ {
boolean matched = false; boolean matched = false;
for (ItemStack item : (ArrayList<ItemStack>)target) for (ItemStack item : (ArrayList<ItemStack>)target)
{ {
matched = matched || checkItemEquals(item, slot); matched = matched || checkItemEquals(item, slot);
} }
if (!matched) if (!matched)
{ {
return false; return false;
} }
} }
else if (target == null && slot != null) else if (target == null && slot != null)
{ {
return false; return false;
} }
} }
} }
return true; return true;
} }
private boolean checkItemEquals(ItemStack target, ItemStack input) private boolean checkItemEquals(ItemStack target, ItemStack input)
{ {
if (input == null && target != null || input != null && target == null) if (input == null && target != null || input != null && target == null)
{ {
return false; return false;
} }
return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage())); return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage()));
} }
public void setMirriored(boolean mirrior) public void setMirriored(boolean mirrior)
{ {
mirriored = mirrior; mirriored = mirrior;
} }
} }

View File

@ -1,119 +1,119 @@
package net.minecraft.src.forge.oredict; package net.minecraft.src.forge.oredict;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import net.minecraft.src.Block; import net.minecraft.src.Block;
import net.minecraft.src.CraftingManager; import net.minecraft.src.CraftingManager;
import net.minecraft.src.IRecipe; import net.minecraft.src.IRecipe;
import net.minecraft.src.InventoryCrafting; import net.minecraft.src.InventoryCrafting;
import net.minecraft.src.Item; import net.minecraft.src.Item;
import net.minecraft.src.ItemStack; import net.minecraft.src.ItemStack;
import net.minecraft.src.ShapelessRecipes; import net.minecraft.src.ShapelessRecipes;
public class ShapelessOreRecipe implements IRecipe public class ShapelessOreRecipe implements IRecipe
{ {
private ItemStack output = null; private ItemStack output = null;
private ArrayList input = new ArrayList(); private ArrayList input = new ArrayList();
public ShapelessOreRecipe(Block result, Object... recipe){ this(new ItemStack(result), recipe); } public ShapelessOreRecipe(Block result, Object... recipe){ this(new ItemStack(result), recipe); }
public ShapelessOreRecipe(Item result, Object... recipe){ this(new ItemStack(result), recipe); } public ShapelessOreRecipe(Item result, Object... recipe){ this(new ItemStack(result), recipe); }
public ShapelessOreRecipe(ItemStack result, Object... recipe) public ShapelessOreRecipe(ItemStack result, Object... recipe)
{ {
output = result.copy(); output = result.copy();
for (Object in : recipe) for (Object in : recipe)
{ {
if (in instanceof ItemStack) if (in instanceof ItemStack)
{ {
input.add(((ItemStack)in).copy()); input.add(((ItemStack)in).copy());
} }
else if (in instanceof Item) else if (in instanceof Item)
{ {
input.add(new ItemStack((Item)in)); input.add(new ItemStack((Item)in));
} }
else if (in instanceof Block) else if (in instanceof Block)
{ {
input.add(new ItemStack((Block)in)); input.add(new ItemStack((Block)in));
} }
else if (in instanceof String) else if (in instanceof String)
{ {
input.add(OreDictionary.getOres((String)in)); input.add(OreDictionary.getOres((String)in));
} }
else else
{ {
String ret = "Invalid shapeless ore recipe: "; String ret = "Invalid shapeless ore recipe: ";
for (Object tmp : recipe) for (Object tmp : recipe)
{ {
ret += tmp + ", "; ret += tmp + ", ";
} }
ret += output; ret += output;
throw new RuntimeException(ret); throw new RuntimeException(ret);
} }
} }
} }
@Override @Override
public int getRecipeSize(){ return input.size(); } public int getRecipeSize(){ return input.size(); }
@Override @Override
public ItemStack getRecipeOutput(){ return output; } public ItemStack getRecipeOutput(){ return output; }
@Override @Override
public ItemStack getCraftingResult(InventoryCrafting var1){ return output.copy(); } public ItemStack getCraftingResult(InventoryCrafting var1){ return output.copy(); }
@Override @Override
public boolean matches(InventoryCrafting var1) public boolean matches(InventoryCrafting var1)
{ {
ArrayList required = new ArrayList(input); ArrayList required = new ArrayList(input);
for (int x = 0; x < var1.getSizeInventory(); x++) for (int x = 0; x < var1.getSizeInventory(); x++)
{ {
ItemStack slot = var1.getStackInSlot(x); ItemStack slot = var1.getStackInSlot(x);
if (slot != null) if (slot != null)
{ {
boolean inRecipe = false; boolean inRecipe = false;
Iterator req = required.iterator(); Iterator req = required.iterator();
while (req.hasNext()) while (req.hasNext())
{ {
boolean match = false; boolean match = false;
Object next = req.next(); Object next = req.next();
if (next instanceof ItemStack) if (next instanceof ItemStack)
{ {
match = checkItemEquals((ItemStack)next, slot); match = checkItemEquals((ItemStack)next, slot);
} }
else if (next instanceof ArrayList) else if (next instanceof ArrayList)
{ {
for (ItemStack item : (ArrayList<ItemStack>)next) for (ItemStack item : (ArrayList<ItemStack>)next)
{ {
match = match || checkItemEquals(item, slot); match = match || checkItemEquals(item, slot);
} }
} }
if (match) if (match)
{ {
inRecipe = true; inRecipe = true;
required.remove(next); required.remove(next);
break; break;
} }
} }
if (!inRecipe) if (!inRecipe)
{ {
return false; return false;
} }
} }
} }
return required.isEmpty(); return required.isEmpty();
} }
private boolean checkItemEquals(ItemStack target, ItemStack input) private boolean checkItemEquals(ItemStack target, ItemStack input)
{ {
return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage())); return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage()));
} }
} }

View File

@ -1,24 +1,24 @@
package net.minecraft.src.forge.packets; package net.minecraft.src.forge.packets;
import net.minecraft.src.NetworkManager; import net.minecraft.src.NetworkManager;
import net.minecraft.src.Packet; import net.minecraft.src.Packet;
import net.minecraft.src.forge.IPacketHandler; import net.minecraft.src.forge.IPacketHandler;
/** /**
* A helper class used to make a shared interface for sending packets, * A helper class used to make a shared interface for sending packets,
* Should not be used outside the API itself. * Should not be used outside the API itself.
*/ */
public abstract class PacketHandlerBase implements IPacketHandler public abstract class PacketHandlerBase implements IPacketHandler
{ {
public static boolean DEBUG = false; public static boolean DEBUG = false;
/** /**
* Sends out a packet to the specified network manager. * Sends out a packet to the specified network manager.
* This is necessary because NetClientHandler, and * This is necessary because NetClientHandler, and
* NetServerHandler are not on both sides. * NetServerHandler are not on both sides.
* *
* @param network The manager to send the packet to * @param network The manager to send the packet to
* @param packet The packet to send * @param packet The packet to send
*/ */
public abstract void sendPacket(NetworkManager network, Packet packet); public abstract void sendPacket(NetworkManager network, Packet packet);
} }

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="forge_common"/> <classpathentry kind="src" path="forge_common"/>
<classpathentry kind="src" path="minecraft_server"/> <classpathentry kind="src" path="minecraft_server"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="../../jars/bin/jinput.jar"/> <classpathentry kind="lib" path="../../jars/bin/jinput.jar"/>
<classpathentry kind="lib" path="../../jars/bin/lwjgl.jar"/> <classpathentry kind="lib" path="../../jars/bin/lwjgl.jar"/>
<classpathentry kind="lib" path="../../jars/bin/lwjgl_util.jar"/> <classpathentry kind="lib" path="../../jars/bin/lwjgl_util.jar"/>
<classpathentry kind="lib" path="../../jars/minecraft_server.jar"/> <classpathentry kind="lib" path="../../jars/minecraft_server.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@ -1 +1 @@
/bin/ /bin/

View File

@ -1,29 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>forge_server</name> <name>forge_server</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>
<buildSpec> <buildSpec>
<buildCommand> <buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name> <name>org.eclipse.jdt.core.javabuilder</name>
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
</buildSpec> </buildSpec>
<natures> <natures>
<nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jdt.core.javanature</nature>
</natures> </natures>
<linkedResources> <linkedResources>
<link> <link>
<name>forge_common</name> <name>forge_common</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/forge_common</locationURI> <locationURI>PARENT-1-PROJECT_LOC/forge_common</locationURI>
</link> </link>
<link> <link>
<name>minecraft_server</name> <name>minecraft_server</name>
<type>2</type> <type>2</type>
<locationURI>PARENT-1-WORKSPACE_LOC/src_work/minecraft_server</locationURI> <locationURI>PARENT-1-WORKSPACE_LOC/src_work/minecraft_server</locationURI>
</link> </link>
</linkedResources> </linkedResources>
</projectDescription> </projectDescription>

View File

@ -1,65 +1,65 @@
Minecraft Forge Public Licence Minecraft Forge Public Licence
============================== ==============================
Version 1.0 Version 1.0
0. Definitions 0. Definitions
-------------- --------------
Minecraft: Denotes a copy of the Minecraft game licensed by Mojang AB Minecraft: Denotes a copy of the Minecraft game licensed by Mojang AB
User: Anybody that interract with the software in one of the following ways: User: Anybody that interract with the software in one of the following ways:
- play - play
- decompile - decompile
- recompile or compile - recompile or compile
- modify - modify
Minecraft Forge: The Minecraft Forge code, in source form, class file form, as Minecraft Forge: The Minecraft Forge code, in source form, class file form, as
obtained in a standalone fashion or as part of a wider distribution. obtained in a standalone fashion or as part of a wider distribution.
Dependency: Code required to have Minecraft Forge working properly. That can Dependency: Code required to have Minecraft Forge working properly. That can
include dependencies required to compile the code as well as modifications in include dependencies required to compile the code as well as modifications in
the Minecraft sources that are required to have Minecraft Forge working. the Minecraft sources that are required to have Minecraft Forge working.
1. Scope 1. Scope
-------- --------
The present license is granted to any user of Minecraft Forge. As a The present license is granted to any user of Minecraft Forge. As a
prerequisite, a user of Minecraft Forge must own a legally aquired copy of prerequisite, a user of Minecraft Forge must own a legally aquired copy of
Minecraft Minecraft
2. Play rights 2. Play rights
-------------- --------------
The user of Minecraft Forge is allowed to install the software on a client or The user of Minecraft Forge is allowed to install the software on a client or
a server and to play it without restriction. a server and to play it without restriction.
3. Modification rights 3. Modification rights
---------------------- ----------------------
The user has the right to decompile the source code, look at either the The user has the right to decompile the source code, look at either the
decompiled version or the original source code, and to modify it. decompiled version or the original source code, and to modify it.
4. Derivation rights 4. Derivation rights
-------------------- --------------------
The user has the rights to derive code from Minecraft Forge, that is to say to The user has the rights to derive code from Minecraft Forge, that is to say to
write code that either extends Minecraft Forge class and interfaces, write code that either extends Minecraft Forge class and interfaces,
instantiate the objects declared or calls the functions. This code is known as instantiate the objects declared or calls the functions. This code is known as
"derived" code, and can be licensed with conditions different from Minecraft "derived" code, and can be licensed with conditions different from Minecraft
Forge. Forge.
5. Distribution rights 5. Distribution rights
---------------------- ----------------------
The user of Minecraft Forge is allowed to redistribute Minecraft Forge in The user of Minecraft Forge is allowed to redistribute Minecraft Forge in
partially, in totallity, or included in a distribution. When distributing partially, in totallity, or included in a distribution. When distributing
binaries or class files, the user must provide means to obtain the sources of binaries or class files, the user must provide means to obtain the sources of
the distributed version of Minecraft Forge at no costs. This includes the the distributed version of Minecraft Forge at no costs. This includes the
files as well as any dependency that the code may rely on, including patches to files as well as any dependency that the code may rely on, including patches to
minecraft original sources. minecraft original sources.
Modification of Minecraft Forge as well as dependencies, including patches to Modification of Minecraft Forge as well as dependencies, including patches to
minecraft original sources, has to remain under the terms of the present minecraft original sources, has to remain under the terms of the present
license. license.

View File

@ -1,10 +1,10 @@
IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License. IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,40 +1,40 @@
SoundSystem CodecIBXM Class License: SoundSystem CodecIBXM Class License:
You are free to use this class for any purpose, commercial or otherwise. You are free to use this class for any purpose, commercial or otherwise.
You may modify this class or source code, and distribute it any way you You may modify this class or source code, and distribute it any way you
like, provided the following conditions are met: like, provided the following conditions are met:
1) You may not falsely claim to be the author of this class or any 1) You may not falsely claim to be the author of this class or any
unmodified portion of it. unmodified portion of it.
2) You may not copyright this class or a modified version of it and then 2) You may not copyright this class or a modified version of it and then
sue me for copyright infringement. sue me for copyright infringement.
3) If you modify the source code, you must clearly document the changes 3) If you modify the source code, you must clearly document the changes
made before redistributing the modified source code, so other users know made before redistributing the modified source code, so other users know
it is not the original code. it is not the original code.
4) You are not required to give me credit for this class in any derived 4) You are not required to give me credit for this class in any derived
work, but if you do, you must also mention my website: work, but if you do, you must also mention my website:
http://www.paulscode.com http://www.paulscode.com
5) I the author will not be responsible for any damages (physical, 5) I the author will not be responsible for any damages (physical,
financial, or otherwise) caused by the use if this class or any financial, or otherwise) caused by the use if this class or any
portion of it. portion of it.
6) I the author do not guarantee, warrant, or make any representations, 6) I the author do not guarantee, warrant, or make any representations,
either expressed or implied, regarding the use of this class or any either expressed or implied, regarding the use of this class or any
portion of it. portion of it.
Author: Paul Lamb Author: Paul Lamb
http://www.paulscode.com http://www.paulscode.com
This software is based on or using the IBXM library available from This software is based on or using the IBXM library available from
http://www.geocities.com/sunet2000/ http://www.geocities.com/sunet2000/
IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License. IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD License.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. Neither the name of mumart nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,22 +1,22 @@
*** HOW TO INSTALL *** *** HOW TO INSTALL ***
Extract the download archive directly into your MCP-directiory. Extract the download archive directly into your MCP-directiory.
It should create a folder "forge" within that directory, containing all It should create a folder "forge" within that directory, containing all
extracted files. extracted files.
You should use freshly downloaded jars, add NOTHING to the jars, ModLoader You should use freshly downloaded jars, add NOTHING to the jars, ModLoader
is no longer needed. Both client and server should be 100% clean. is no longer needed. Both client and server should be 100% clean.
You also need to install the FernFlower decompiler, you can download it at You also need to install the FernFlower decompiler, you can download it at
http://goo.gl/PnJHp. Extract fernflower.jar into your MCP's runtime/bin folder. http://goo.gl/PnJHp. Extract fernflower.jar into your MCP's runtime/bin folder.
Now just start the install.cmd/.sh, MCForge will install itself into the proper Now just start the install.cmd/.sh, MCForge will install itself into the proper
locations and copy all needed files, as well as modifying the needed baseclasses. locations and copy all needed files, as well as modifying the needed baseclasses.
Forge also includes a snapshot of the MCP mapings, this may not be the current Forge also includes a snapshot of the MCP mapings, this may not be the current
version of the mapings. But you must use the provided mapings in order for the version of the mapings. But you must use the provided mapings in order for the
patch files to work together. patch files to work together.
The install scripts should take care of everything for you, so you should not need The install scripts should take care of everything for you, so you should not need
to run ANY MCP script before installing forge. to run ANY MCP script before installing forge.

View File

@ -1,3 +1,3 @@
@echo off @echo off
..\runtime\bin\python\python_mcp install.py ..\runtime\bin\python\python_mcp install.py
pause pause

View File

@ -1,105 +1,105 @@
import os, os.path, sys import os, os.path, sys
import urllib, zipfile import urllib, zipfile
import shutil, glob, fnmatch import shutil, glob, fnmatch
import subprocess, logging import subprocess, logging
forge_dir = os.path.dirname(os.path.abspath(__file__)) forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..') mcp_dir = os.path.abspath('..')
src_dir = os.path.join(mcp_dir, 'src') src_dir = os.path.join(mcp_dir, 'src')
sys.path.append(mcp_dir) sys.path.append(mcp_dir)
from runtime.decompile import decompile from runtime.decompile import decompile
from runtime.updatenames import updatenames from runtime.updatenames import updatenames
from runtime.updatemd5 import updatemd5 from runtime.updatemd5 import updatemd5
from runtime.cleanup import cleanup from runtime.cleanup import cleanup
from runtime.updatemcp import updatemcp from runtime.updatemcp import updatemcp
from forge import apply_patches, copytree, reset_logger, download_ff, cleanup_source, pre_decompile, post_decompile from forge import apply_patches, copytree, reset_logger, download_ff, cleanup_source, pre_decompile, post_decompile
def main(): def main():
print '=================================== Minecraft Forge Setup Start =================================' print '=================================== Minecraft Forge Setup Start ================================='
if os.path.isdir(os.path.join(mcp_dir, 'conf')): if os.path.isdir(os.path.join(mcp_dir, 'conf')):
shutil.rmtree(os.path.join(mcp_dir, 'conf')) shutil.rmtree(os.path.join(mcp_dir, 'conf'))
copytree(os.path.join(forge_dir, 'conf'), os.path.join(mcp_dir, 'conf')) copytree(os.path.join(forge_dir, 'conf'), os.path.join(mcp_dir, 'conf'))
if os.path.isdir(src_dir): if os.path.isdir(src_dir):
os.chdir(mcp_dir) os.chdir(mcp_dir)
cleanup(None, False) cleanup(None, False)
reset_logger() reset_logger()
os.chdir(forge_dir) os.chdir(forge_dir)
if os.path.isdir(src_dir): if os.path.isdir(src_dir):
print 'Please make sure to backup your modified files, and say yes when it asks you to do cleanup.' print 'Please make sure to backup your modified files, and say yes when it asks you to do cleanup.'
sys.exit(1) sys.exit(1)
if not download_ff(mcp_dir): if not download_ff(mcp_dir):
sys.exit(1) sys.exit(1)
try: try:
pre_decompile() pre_decompile()
os.chdir(mcp_dir) os.chdir(mcp_dir)
# Conf JAD CSV -r -d -a -n -p -o -l -g # Conf JAD CSV -r -d -a -n -p -o -l -g
decompile(None, False, False, True, True, False, True, False, False, False, False) decompile(None, False, False, True, True, False, True, False, False, False, False)
reset_logger() reset_logger()
os.chdir(forge_dir) os.chdir(forge_dir)
post_decompile() post_decompile()
except SystemExit, e: except SystemExit, e:
print 'Decompile Exception: %d ' % e.code print 'Decompile Exception: %d ' % e.code
raise e raise e
if not os.path.isdir(src_dir): if not os.path.isdir(src_dir):
print 'Something went wrong, src folder not found at: %s' % src_dir print 'Something went wrong, src folder not found at: %s' % src_dir
sys.exit(1) sys.exit(1)
cleanup_source(src_dir) cleanup_source(src_dir)
has_client = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft')) has_client = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft'))
has_server = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft_server')) has_server = os.path.isdir(os.path.join(mcp_dir, 'src', 'minecraft_server'))
fml_dir = os.path.join(forge_dir, 'fml') fml_dir = os.path.join(forge_dir, 'fml')
print 'Applying Forge ModLoader patches' print 'Applying Forge ModLoader patches'
if has_client: if has_client:
if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft')): if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft')):
apply_patches(os.path.join(fml_dir, 'patches', 'minecraft'), src_dir) apply_patches(os.path.join(fml_dir, 'patches', 'minecraft'), src_dir)
if os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft')): if os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft')):
copytree(os.path.join(fml_dir, 'src', 'minecraft'), os.path.join(src_dir, 'minecraft')) copytree(os.path.join(fml_dir, 'src', 'minecraft'), os.path.join(src_dir, 'minecraft'))
if has_server: if has_server:
if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft_server')): if os.path.isdir(os.path.join(fml_dir, 'patches', 'minecraft_server')):
apply_patches(os.path.join(fml_dir, 'patches', 'minecraft_server'), src_dir) apply_patches(os.path.join(fml_dir, 'patches', 'minecraft_server'), src_dir)
if os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft_server')): if os.path.isdir(os.path.join(fml_dir, 'src', 'minecraft_server')):
copytree(os.path.join(fml_dir, 'src', 'minecraft_server'), os.path.join(src_dir, 'minecraft_server')) copytree(os.path.join(fml_dir, 'src', 'minecraft_server'), os.path.join(src_dir, 'minecraft_server'))
os.chdir(mcp_dir) os.chdir(mcp_dir)
updatenames(None, True) updatenames(None, True)
reset_logger() reset_logger()
os.chdir(forge_dir) os.chdir(forge_dir)
print 'Applying forge patches' print 'Applying forge patches'
if has_client: if has_client:
if os.path.isdir(os.path.join(forge_dir, 'patches', 'minecraft')): if os.path.isdir(os.path.join(forge_dir, 'patches', 'minecraft')):
apply_patches(os.path.join(forge_dir, 'patches', 'minecraft'), src_dir) apply_patches(os.path.join(forge_dir, 'patches', 'minecraft'), src_dir)
if os.path.isdir(os.path.join(forge_dir, 'src', 'minecraft')): if os.path.isdir(os.path.join(forge_dir, 'src', 'minecraft')):
copytree(os.path.join(forge_dir, 'src', 'minecraft'), os.path.join(src_dir, 'minecraft')) copytree(os.path.join(forge_dir, 'src', 'minecraft'), os.path.join(src_dir, 'minecraft'))
if has_server: if has_server:
if os.path.isdir(os.path.join(forge_dir, 'patches', 'minecraft_server')): if os.path.isdir(os.path.join(forge_dir, 'patches', 'minecraft_server')):
apply_patches(os.path.join(forge_dir, 'patches', 'minecraft_server'), src_dir) apply_patches(os.path.join(forge_dir, 'patches', 'minecraft_server'), src_dir)
if os.path.isdir(os.path.join(forge_dir, 'src', 'minecraft_server')): if os.path.isdir(os.path.join(forge_dir, 'src', 'minecraft_server')):
copytree(os.path.join(forge_dir, 'src', 'minecraft_server'), os.path.join(src_dir, 'minecraft_server')) copytree(os.path.join(forge_dir, 'src', 'minecraft_server'), os.path.join(src_dir, 'minecraft_server'))
os.chdir(mcp_dir) os.chdir(mcp_dir)
updatemcp(None, True) updatemcp(None, True)
reset_logger() reset_logger()
updatenames(None, True) updatenames(None, True)
reset_logger() reset_logger()
updatemd5(None, True) updatemd5(None, True)
reset_logger() reset_logger()
os.chdir(forge_dir) os.chdir(forge_dir)
print '=================================== Minecraft Forge Setup Finished =================================' print '=================================== Minecraft Forge Setup Finished ================================='
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,28 +1,28 @@
@echo off @echo off
if "%1"=="" ( if "%1"=="" (
echo You must enter a build number to promote to the latest echo You must enter a build number to promote to the latest
exit /b 1 exit /b 1
) )
echo Jenkins build script started for build #%1 echo Jenkins build script started for build #%1
rmdir /S /Q ..\conf rmdir /S /Q ..\conf
xcopy /Y /E /I conf\* ..\conf xcopy /Y /E /I conf\* ..\conf
..\runtime\bin\python\python_mcp setup.py -skipdecompile ..\runtime\bin\python\python_mcp setup.py -skipdecompile
if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
..\runtime\bin\python\python_mcp release.py %1 ..\runtime\bin\python\python_mcp release.py %1
if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL% if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
cd forge-*%1 cd forge-*%1
if %ERRORLEVEL% NEQ 0 ( if %ERRORLEVEL% NEQ 0 (
echo Release failed to produce artifacts %1 echo Release failed to produce artifacts %1
exit /b 1 exit /b 1
) )
for /f "delims=\" %%a in ("%cd%") do SET VERSION=%%~nxa for /f "delims=\" %%a in ("%cd%") do SET VERSION=%%~nxa
SET VERSION=%VERSION:~6% SET VERSION=%VERSION:~6%
echo Forge Version: %VERSION% echo Forge Version: %VERSION%
..\..\MediafireUploader.exe Forge-%VERSION% minecraftforge-client-%VERSION%.zip minecraftforge-server-%VERSION%.zip minecraftforge-src-%VERSION%.zip ..\..\MediafireUploader.exe Forge-%VERSION% minecraftforge-client-%VERSION%.zip minecraftforge-server-%VERSION%.zip minecraftforge-src-%VERSION%.zip

View File

@ -1,203 +1,203 @@
import os, os.path, sys import os, os.path, sys
import shutil, fnmatch import shutil, fnmatch
import logging, zipfile, re import logging, zipfile, re
forge_dir = os.path.dirname(os.path.abspath(__file__)) forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..') mcp_dir = os.path.abspath('..')
src_dir = os.path.join(mcp_dir, 'src') src_dir = os.path.join(mcp_dir, 'src')
sys.path.append(mcp_dir) sys.path.append(mcp_dir)
from runtime.reobfuscate import reobfuscate from runtime.reobfuscate import reobfuscate
from forge import reset_logger, load_version, zip_folder, zip_create, inject_version from forge import reset_logger, load_version, zip_folder, zip_create, inject_version
from build import build from build import build
reobf_dir = os.path.join(mcp_dir, 'reobf') reobf_dir = os.path.join(mcp_dir, 'reobf')
client_dir = os.path.join(reobf_dir, 'minecraft') client_dir = os.path.join(reobf_dir, 'minecraft')
server_dir = os.path.join(reobf_dir, 'minecraft_server') server_dir = os.path.join(reobf_dir, 'minecraft_server')
zip = None zip = None
zip_name = None zip_name = None
zip_base = None zip_base = None
version_str = None version_str = None
def main(): def main():
global version_str global version_str
build_num = 0 build_num = 0
if len(sys.argv) > 1: if len(sys.argv) > 1:
try: try:
build_num = int(sys.argv[1]) build_num = int(sys.argv[1])
except: except:
pass pass
ret = 0 ret = 0
ret = build(build_num) ret = build(build_num)
if ret != 0: if ret != 0:
sys.exit(ret) sys.exit(ret)
print '=================================== Release Start =================================' print '=================================== Release Start ================================='
error_level = 0 error_level = 0
try: try:
os.chdir(mcp_dir) os.chdir(mcp_dir)
reset_logger() reset_logger()
reobfuscate(None, False, True, True) reobfuscate(None, False, True, True)
reset_logger() reset_logger()
os.chdir(forge_dir) os.chdir(forge_dir)
except SystemExit, e: except SystemExit, e:
print 'Reobfusicate Exception: %d ' % e.code print 'Reobfusicate Exception: %d ' % e.code
error_level = e.code error_level = e.code
extract_fml_obfed() extract_fml_obfed()
version = load_version(build_num) version = load_version(build_num)
version_str = '%d.%d.%d.%d' % (version['major'], version['minor'], version['revision'], version['build']) version_str = '%d.%d.%d.%d' % (version['major'], version['minor'], version['revision'], version['build'])
out_folder = os.path.join(forge_dir, 'forge-%s' % version_str) out_folder = os.path.join(forge_dir, 'forge-%s' % version_str)
if os.path.isdir(out_folder): if os.path.isdir(out_folder):
shutil.rmtree(out_folder) shutil.rmtree(out_folder)
os.makedirs(out_folder) os.makedirs(out_folder)
update_info('forge_common/mod_MinecraftForge.info', version_str) update_info('forge_common/mod_MinecraftForge.info', version_str)
zip_start('minecraftforge-client-%s.zip' % version_str) zip_start('minecraftforge-client-%s.zip' % version_str)
zip_folder(client_dir, '', zip) zip_folder(client_dir, '', zip)
zip_add('forge_common/mod_MinecraftForge.info', 'mod_MinecraftForge.info') zip_add('forge_common/mod_MinecraftForge.info', 'mod_MinecraftForge.info')
zip_add('forge_client/src/forge_logo.png') zip_add('forge_client/src/forge_logo.png')
zip_add('install/MinecraftForge-Credits.txt') zip_add('install/MinecraftForge-Credits.txt')
zip_add('install/MinecraftForge-License.txt') zip_add('install/MinecraftForge-License.txt')
zip_add('fml/CREDITS-fml.txt') zip_add('fml/CREDITS-fml.txt')
zip_add('fml/LICENSE-fml.txt') zip_add('fml/LICENSE-fml.txt')
zip_add('fml/README-fml.txt') zip_add('fml/README-fml.txt')
zip_add('fml/src/minecraft/fmlversion.properties') zip_add('fml/src/minecraft/fmlversion.properties')
zip_add('install/Paulscode IBXM Library License.txt') zip_add('install/Paulscode IBXM Library License.txt')
zip_add('install/Paulscode SoundSystem CodecIBXM License.txt') zip_add('install/Paulscode SoundSystem CodecIBXM License.txt')
zip_end() zip_end()
zip_start('minecraftforge-server-%s.zip' % version_str) zip_start('minecraftforge-server-%s.zip' % version_str)
zip_folder(server_dir, '', zip) zip_folder(server_dir, '', zip)
zip_add('forge_common/mod_MinecraftForge.info', 'mod_MinecraftForge.info') zip_add('forge_common/mod_MinecraftForge.info', 'mod_MinecraftForge.info')
zip_add('install/MinecraftForge-Credits.txt') zip_add('install/MinecraftForge-Credits.txt')
zip_add('install/MinecraftForge-License.txt') zip_add('install/MinecraftForge-License.txt')
zip_add('fml/CREDITS-fml.txt') zip_add('fml/CREDITS-fml.txt')
zip_add('fml/LICENSE-fml.txt') zip_add('fml/LICENSE-fml.txt')
zip_add('fml/README-fml.txt') zip_add('fml/README-fml.txt')
zip_add('fml/src/minecraft_server/fmlversion.properties') zip_add('fml/src/minecraft_server/fmlversion.properties')
zip_end() zip_end()
inject_version(os.path.join(forge_dir, 'forge_common', 'net', 'minecraft', 'src', 'forge', 'ForgeHooks.java'), build_num) inject_version(os.path.join(forge_dir, 'forge_common', 'net', 'minecraft', 'src', 'forge', 'ForgeHooks.java'), build_num)
zip_start('minecraftforge-src-%s.zip' % version_str, 'forge') zip_start('minecraftforge-src-%s.zip' % version_str, 'forge')
zip_add('forge_client/src', 'src/minecraft') zip_add('forge_client/src', 'src/minecraft')
zip_add('forge_server/src', 'src/minecraft_server') zip_add('forge_server/src', 'src/minecraft_server')
zip_add('forge_common', 'src/minecraft') zip_add('forge_common', 'src/minecraft')
zip_add('forge_common', 'src/minecraft_server') zip_add('forge_common', 'src/minecraft_server')
zip_add('patches', 'patches') zip_add('patches', 'patches')
zip_add('fml', 'fml') zip_add('fml', 'fml')
zip_add('conf', 'conf') zip_add('conf', 'conf')
zip_add('install/install.cmd') zip_add('install/install.cmd')
zip_add('install/install.sh') zip_add('install/install.sh')
zip_add('install/README-MinecraftForge.txt') zip_add('install/README-MinecraftForge.txt')
zip_add('install/install.py') zip_add('install/install.py')
zip_add('forge.py') zip_add('forge.py')
zip_add('install/MinecraftForge-Credits.txt') zip_add('install/MinecraftForge-Credits.txt')
zip_add('install/MinecraftForge-License.txt') zip_add('install/MinecraftForge-License.txt')
zip_add('install/Paulscode IBXM Library License.txt') zip_add('install/Paulscode IBXM Library License.txt')
zip_add('install/Paulscode SoundSystem CodecIBXM License.txt') zip_add('install/Paulscode SoundSystem CodecIBXM License.txt')
zip_end() zip_end()
inject_version(os.path.join(forge_dir, 'forge_common', 'net', 'minecraft', 'src', 'forge', 'ForgeHooks.java'), 0) inject_version(os.path.join(forge_dir, 'forge_common', 'net', 'minecraft', 'src', 'forge', 'ForgeHooks.java'), 0)
shutil.move(os.path.join(forge_dir, 'file.backup'), os.path.join(forge_dir, 'forge_common/mod_MinecraftForge.info'.replace('/', os.sep))) shutil.move(os.path.join(forge_dir, 'file.backup'), os.path.join(forge_dir, 'forge_common/mod_MinecraftForge.info'.replace('/', os.sep)))
print '=================================== Release Finished %d =================================' % error_level print '=================================== Release Finished %d =================================' % error_level
sys.exit(error_level) sys.exit(error_level)
def zip_add(file, key=None): def zip_add(file, key=None):
if key == None: if key == None:
key = os.path.basename(file) key = os.path.basename(file)
else: else:
key = key.replace('/', os.sep) key = key.replace('/', os.sep)
if not zip_base is None: if not zip_base is None:
key = os.path.join(zip_base, key) key = os.path.join(zip_base, key)
file = os.path.join(forge_dir, file.replace('/', os.sep)) file = os.path.join(forge_dir, file.replace('/', os.sep))
if os.path.isdir(file): if os.path.isdir(file):
zip_folder(file, key, zip) zip_folder(file, key, zip)
else: else:
if os.path.isfile(file): if os.path.isfile(file):
print key print key
zip.write(file, key) zip.write(file, key)
def zip_add_perm(file, perm, key=None): def zip_add_perm(file, perm, key=None):
if key == None: if key == None:
key = os.path.basename(file) key = os.path.basename(file)
else: else:
key = key.replace('/', os.sep) key = key.replace('/', os.sep)
if not zip_base is None: if not zip_base is None:
key = os.path.join(zip_base, key) key = os.path.join(zip_base, key)
file = os.path.join(forge_dir, file.replace('/', os.sep)) file = os.path.join(forge_dir, file.replace('/', os.sep))
if os.path.isfile(file): if os.path.isfile(file):
print key print key
#zip.write(file, key) #zip.write(file, key)
with open(file, 'r') as fh: data = fh.read() with open(file, 'r') as fh: data = fh.read()
info = zipfile.ZipInfo(key) info = zipfile.ZipInfo(key)
info.external_attr = 0777 << 16L info.external_attr = 0777 << 16L
zip.writestr(info, data) zip.writestr(info, data)
def zip_start(name, base=None): def zip_start(name, base=None):
global zip, zip_name, zip_base global zip, zip_name, zip_base
zip_name = name zip_name = name
print '=================================== %s Start =================================' % zip_name print '=================================== %s Start =================================' % zip_name
zip_file = os.path.join(forge_dir, 'forge-%s' % version_str, name) zip_file = os.path.join(forge_dir, 'forge-%s' % version_str, name)
zip = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) zip = zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED)
zip_base = base zip_base = base
def zip_end(): def zip_end():
global zip, zip_name, zip_base global zip, zip_name, zip_base
zip.close() zip.close()
print '=================================== %s Finished =================================' % zip_name print '=================================== %s Finished =================================' % zip_name
zip_name = None zip_name = None
zip_base = None zip_base = None
def update_info(input, version): def update_info(input, version):
input = os.path.join(forge_dir, input.replace('/', os.sep)) input = os.path.join(forge_dir, input.replace('/', os.sep))
temp = os.path.join(forge_dir, 'file.backup') temp = os.path.join(forge_dir, 'file.backup')
shutil.move(input, temp) shutil.move(input, temp)
with open(temp, 'r') as fh: with open(temp, 'r') as fh:
buf = fh.read() buf = fh.read()
buf = re.sub(r'{version}', version, buf) buf = re.sub(r'{version}', version, buf)
with open(input, 'w') as fh: with open(input, 'w') as fh:
fh.write(buf) fh.write(buf)
def extract_fml_obfed(): def extract_fml_obfed():
fml_file = os.path.join(forge_dir, 'fml', 'difflist.txt') fml_file = os.path.join(forge_dir, 'fml', 'difflist.txt')
if not os.path.isfile(fml_file): if not os.path.isfile(fml_file):
print 'Could not find Forge ModLoader\'s DiffList, looking for it at: %s' % fml_file print 'Could not find Forge ModLoader\'s DiffList, looking for it at: %s' % fml_file
sys.exit(1) sys.exit(1)
with open(fml_file, 'r') as fh: with open(fml_file, 'r') as fh:
lines = fh.readlines() lines = fh.readlines()
client = zipfile.ZipFile(os.path.join(mcp_dir, 'temp', 'client_reobf.jar')) client = zipfile.ZipFile(os.path.join(mcp_dir, 'temp', 'client_reobf.jar'))
server = zipfile.ZipFile(os.path.join(mcp_dir, 'temp', 'server_reobf.jar')) server = zipfile.ZipFile(os.path.join(mcp_dir, 'temp', 'server_reobf.jar'))
print 'Extracting Reobfed Forge ModLoader classes' print 'Extracting Reobfed Forge ModLoader classes'
lines.append("minecraft/net/minecraft/client/MinecraftApplet.class") #Needed because users dont install Forge properly -.- lines.append("minecraft/net/minecraft/client/MinecraftApplet.class") #Needed because users dont install Forge properly -.-
for line in lines: for line in lines:
line = line.replace('\n', '').replace('\r', '').replace('/', os.sep) line = line.replace('\n', '').replace('\r', '').replace('/', os.sep)
print line print line
if not os.path.isfile(os.path.join(reobf_dir, line)): if not os.path.isfile(os.path.join(reobf_dir, line)):
side = line.split(os.sep)[0] side = line.split(os.sep)[0]
if side == 'minecraft': if side == 'minecraft':
client.extract(line[10:].replace(os.sep, '/'), client_dir) client.extract(line[10:].replace(os.sep, '/'), client_dir)
else: else:
server.extract(line[17:].replace(os.sep, '/'), server_dir) server.extract(line[17:].replace(os.sep, '/'), server_dir)
client.close() client.close()
server.close() server.close()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,5 +1,5 @@
@echo off @echo off
..\runtime\bin\python\python_mcp setup.py %* ..\runtime\bin\python\python_mcp setup.py %*
if NOT "%1"=="-skipdecompile" ( if NOT "%1"=="-skipdecompile" (
pause pause
) )

View File

@ -1,102 +1,102 @@
import os, os.path, sys import os, os.path, sys
import urllib, zipfile import urllib, zipfile
import shutil, glob, fnmatch import shutil, glob, fnmatch
import subprocess, logging import subprocess, logging
forge_dir = os.path.dirname(os.path.abspath(__file__)) forge_dir = os.path.dirname(os.path.abspath(__file__))
mcp_dir = os.path.abspath('..') mcp_dir = os.path.abspath('..')
src_dir = os.path.join(mcp_dir, 'src') src_dir = os.path.join(mcp_dir, 'src')
sys.path.append(mcp_dir) sys.path.append(mcp_dir)
from runtime.decompile import decompile from runtime.decompile import decompile
from runtime.updatenames import updatenames from runtime.updatenames import updatenames
from runtime.updatemd5 import updatemd5 from runtime.updatemd5 import updatemd5
from forge import apply_patches, copytree, reset_logger, download_ff, cleanup_source, pre_decompile, post_decompile from forge import apply_patches, copytree, reset_logger, download_ff, cleanup_source, pre_decompile, post_decompile
def main(): def main():
print '=================================== Setup Start =================================' print '=================================== Setup Start ================================='
skipDecompile = len(sys.argv) > 1 and sys.argv[1] == '-skipdecompile' skipDecompile = len(sys.argv) > 1 and sys.argv[1] == '-skipdecompile'
if not skipDecompile: if not skipDecompile:
if not download_ff(mcp_dir): if not download_ff(mcp_dir):
sys.exit(1) sys.exit(1)
if os.path.isdir(src_dir): if os.path.isdir(src_dir):
shutil.rmtree(src_dir) shutil.rmtree(src_dir)
try: try:
pre_decompile() pre_decompile()
os.chdir(mcp_dir) os.chdir(mcp_dir)
# Conf JAD CSV -r -d -a -n -p -o -l -g # Conf JAD CSV -r -d -a -n -p -o -l -g
decompile(None, False, False, True, True, False, True, False, False, False, False) decompile(None, False, False, True, True, False, True, False, False, False, False)
reset_logger() reset_logger()
os.chdir(forge_dir) os.chdir(forge_dir)
post_decompile() post_decompile()
except SystemExit, e: except SystemExit, e:
print 'Decompile Exception: %d ' % e.code print 'Decompile Exception: %d ' % e.code
raise e raise e
if not os.path.isdir(src_dir): if not os.path.isdir(src_dir):
print 'Something went wrong, src folder not found at: %s' % src_dir print 'Something went wrong, src folder not found at: %s' % src_dir
sys.exit(1) sys.exit(1)
cleanup_source(src_dir) cleanup_source(src_dir)
setup_fml() setup_fml()
os.chdir(mcp_dir) os.chdir(mcp_dir)
updatenames(None, True) updatenames(None, True)
reset_logger() reset_logger()
updatemd5(None, True) updatemd5(None, True)
reset_logger() reset_logger()
os.chdir(forge_dir) os.chdir(forge_dir)
base_dir = os.path.join(mcp_dir, 'src_base') base_dir = os.path.join(mcp_dir, 'src_base')
work_dir = os.path.join(mcp_dir, 'src_work') work_dir = os.path.join(mcp_dir, 'src_work')
if os.path.isdir(base_dir): if os.path.isdir(base_dir):
shutil.rmtree(base_dir) shutil.rmtree(base_dir)
if os.path.isdir(work_dir): if os.path.isdir(work_dir):
shutil.rmtree(work_dir) shutil.rmtree(work_dir)
print 'Setting up source directories' print 'Setting up source directories'
shutil.copytree(src_dir, base_dir) shutil.copytree(src_dir, base_dir)
shutil.copytree(src_dir, work_dir) shutil.copytree(src_dir, work_dir)
print 'Applying forge patches' print 'Applying forge patches'
apply_patches(os.path.join(forge_dir, 'patches'), work_dir) apply_patches(os.path.join(forge_dir, 'patches'), work_dir)
print '=================================== Setup Finished =================================' print '=================================== Setup Finished ================================='
def setup_fml(): def setup_fml():
print 'Setting up Forge ModLoader' print 'Setting up Forge ModLoader'
fml = glob.glob(os.path.join(forge_dir, 'fml-src-*.zip')) fml = glob.glob(os.path.join(forge_dir, 'fml-src-*.zip'))
if not len(fml) == 1: if not len(fml) == 1:
if len(fml) == 0: if len(fml) == 0:
print 'Missing FML source zip, should be named fml-src-*.zip inside your forge folder, obtain it from the repo' print 'Missing FML source zip, should be named fml-src-*.zip inside your forge folder, obtain it from the repo'
else: else:
print 'To many FML source zips found, we should only have one. Check the Forge Git for the latest FML version supported' print 'To many FML source zips found, we should only have one. Check the Forge Git for the latest FML version supported'
sys.exit(1) sys.exit(1)
fml_dir = os.path.join(forge_dir, 'fml') fml_dir = os.path.join(forge_dir, 'fml')
if os.path.isdir(fml_dir): if os.path.isdir(fml_dir):
shutil.rmtree(fml_dir) shutil.rmtree(fml_dir)
print 'Extracting: %s' % os.path.basename(fml[0]) print 'Extracting: %s' % os.path.basename(fml[0])
zf = zipfile.ZipFile(fml[0]) zf = zipfile.ZipFile(fml[0])
zf.extractall(forge_dir) zf.extractall(forge_dir)
zf.close() zf.close()
print 'Applying Forge ModLoader patches' print 'Applying Forge ModLoader patches'
apply_patches(os.path.join(fml_dir, 'patches'), src_dir) apply_patches(os.path.join(fml_dir, 'patches'), src_dir)
copytree(os.path.join(fml_dir, 'src'), src_dir) copytree(os.path.join(fml_dir, 'src'), src_dir)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -1,3 +1,3 @@
@echo off @echo off
set PATH=.\bin;%PATH% set PATH=.\bin;%PATH%
..\runtime\bin\python\python_mcp update_patches.py ..\runtime\bin\python\python_mcp update_patches.py