diff --git a/patches/minecraft/net/minecraft/init/Biomes.java.patch b/patches/minecraft/net/minecraft/init/Biomes.java.patch new file mode 100644 index 000000000..184c22dfe --- /dev/null +++ b/patches/minecraft/net/minecraft/init/Biomes.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/Biomes.java ++++ b/net/minecraft/init/Biomes.java +@@ -3,6 +3,7 @@ + import net.minecraft.util.ResourceLocation; + import net.minecraft.world.biome.Biome; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public abstract class Biomes { + public static final Biome OCEAN; + public static final Biome DEFAULT; diff --git a/patches/minecraft/net/minecraft/init/Blocks.java.patch b/patches/minecraft/net/minecraft/init/Blocks.java.patch new file mode 100644 index 000000000..a3199cc0f --- /dev/null +++ b/patches/minecraft/net/minecraft/init/Blocks.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/Blocks.java ++++ b/net/minecraft/init/Blocks.java +@@ -5,6 +5,7 @@ + import net.minecraft.block.Block; + import net.minecraft.util.ResourceLocation; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class Blocks { + private static final Set CACHE; + public static final Block AIR; diff --git a/patches/minecraft/net/minecraft/init/Enchantments.java.patch b/patches/minecraft/net/minecraft/init/Enchantments.java.patch new file mode 100644 index 000000000..646e0321c --- /dev/null +++ b/patches/minecraft/net/minecraft/init/Enchantments.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/Enchantments.java ++++ b/net/minecraft/init/Enchantments.java +@@ -4,6 +4,7 @@ + import net.minecraft.enchantment.Enchantment; + import net.minecraft.util.ResourceLocation; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class Enchantments { + public static final Enchantment PROTECTION = getRegisteredEnchantment("protection"); + public static final Enchantment FIRE_PROTECTION = getRegisteredEnchantment("fire_protection"); diff --git a/patches/minecraft/net/minecraft/init/Fluids.java.patch b/patches/minecraft/net/minecraft/init/Fluids.java.patch new file mode 100644 index 000000000..12f17baac --- /dev/null +++ b/patches/minecraft/net/minecraft/init/Fluids.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/Fluids.java ++++ b/net/minecraft/init/Fluids.java +@@ -6,6 +6,7 @@ + import net.minecraft.fluid.Fluid; + import net.minecraft.util.ResourceLocation; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class Fluids { + private static final Set field_207214_f; + public static final Fluid field_204541_a; diff --git a/patches/minecraft/net/minecraft/init/Items.java.patch b/patches/minecraft/net/minecraft/init/Items.java.patch new file mode 100644 index 000000000..ac247926c --- /dev/null +++ b/patches/minecraft/net/minecraft/init/Items.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/Items.java ++++ b/net/minecraft/init/Items.java +@@ -3,6 +3,7 @@ + import net.minecraft.item.Item; + import net.minecraft.util.ResourceLocation; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class Items { + public static final Item AIR; + public static final Item IRON_SHOVEL; diff --git a/patches/minecraft/net/minecraft/init/MobEffects.java.patch b/patches/minecraft/net/minecraft/init/MobEffects.java.patch new file mode 100644 index 000000000..79cb95890 --- /dev/null +++ b/patches/minecraft/net/minecraft/init/MobEffects.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/MobEffects.java ++++ b/net/minecraft/init/MobEffects.java +@@ -4,6 +4,7 @@ + import net.minecraft.potion.Potion; + import net.minecraft.util.ResourceLocation; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class MobEffects { + public static final Potion SPEED; + public static final Potion SLOWNESS; diff --git a/patches/minecraft/net/minecraft/init/Particles.java.patch b/patches/minecraft/net/minecraft/init/Particles.java.patch new file mode 100644 index 000000000..4ae3a14fb --- /dev/null +++ b/patches/minecraft/net/minecraft/init/Particles.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/Particles.java ++++ b/net/minecraft/init/Particles.java +@@ -7,6 +7,7 @@ + import net.minecraft.particles.RedstoneParticleData; + import net.minecraft.util.ResourceLocation; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class Particles { + public static final BasicParticleType field_197608_a; + public static final BasicParticleType field_197609_b; diff --git a/patches/minecraft/net/minecraft/init/PotionTypes.java.patch b/patches/minecraft/net/minecraft/init/PotionTypes.java.patch new file mode 100644 index 000000000..61d0c36af --- /dev/null +++ b/patches/minecraft/net/minecraft/init/PotionTypes.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/PotionTypes.java ++++ b/net/minecraft/init/PotionTypes.java +@@ -5,6 +5,7 @@ + import net.minecraft.potion.PotionType; + import net.minecraft.util.ResourceLocation; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class PotionTypes { + private static final Set CACHE; + public static final PotionType EMPTY; diff --git a/patches/minecraft/net/minecraft/init/SoundEvents.java.patch b/patches/minecraft/net/minecraft/init/SoundEvents.java.patch new file mode 100644 index 000000000..47f136300 --- /dev/null +++ b/patches/minecraft/net/minecraft/init/SoundEvents.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/init/SoundEvents.java ++++ b/net/minecraft/init/SoundEvents.java +@@ -3,6 +3,7 @@ + import net.minecraft.util.ResourceLocation; + import net.minecraft.util.SoundEvent; + ++@net.minecraftforge.registries.ObjectHolder("minecraft") + public class SoundEvents { + public static final SoundEvent AMBIENT_CAVE; + public static final SoundEvent field_204326_e; diff --git a/patches/minecraft/net/minecraft/item/ArmorMaterial.java.patch b/patches/minecraft/net/minecraft/item/ArmorMaterial.java.patch new file mode 100644 index 000000000..acaf8a808 --- /dev/null +++ b/patches/minecraft/net/minecraft/item/ArmorMaterial.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/item/ArmorMaterial.java ++++ b/net/minecraft/item/ArmorMaterial.java +@@ -77,4 +77,8 @@ + public float func_200901_e() { + return this.toughness; + } ++ ++ public static ArmorMaterial create(String name, String p_i48533_3_, int p_i48533_4_, int[] p_i48533_5_, int p_i48533_6_, SoundEvent p_i48533_7_, float p_i48533_8_, Supplier p_i48533_9_) { ++ return null; + } ++} diff --git a/src/main/java/ibxm/Channel.java b/src/main/java/ibxm/Channel.java deleted file mode 100644 index 1ab5bb8a2..000000000 --- a/src/main/java/ibxm/Channel.java +++ /dev/null @@ -1,947 +0,0 @@ - -package ibxm; - -public class Channel { - public int pattern_loop_row; - - private Module module; - private Instrument instrument; - private Sample sample; - private int[] global_volume, current_note; - private boolean linear_periods, fast_volume_slides, key_on, silent; - private int sample_idx, sample_frac, step, left_gain, right_gain; - @SuppressWarnings("unused") //Forge - private int volume, panning, fine_tune, period, porta_period, key_add; - private int tremolo_speed, tremolo_depth, tremolo_tick, tremolo_wave, tremolo_add; - private int vibrato_speed, vibrato_depth, vibrato_tick, vibrato_wave, vibrato_add; - private int volume_slide_param, portamento_param, retrig_param; - private int volume_envelope_tick, panning_envelope_tick; - private int effect_tick, trigger_tick, fade_out_volume, random_seed; - - private int log_2_sampling_rate; - private static final int LOG_2_29024 = LogTable.log_2( 29024 ); - private static final int LOG_2_8287 = LogTable.log_2( 8287 ); - private static final int LOG_2_8363 = LogTable.log_2( 8363 ); - private static final int LOG_2_1712 = LogTable.log_2( 1712 ); - - private static final int[] sine_table = new int[] { - 0, 24 , 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, - 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24 - }; - - public Channel( Module mod, int sampling_rate, int[] global_vol ) { - module = mod; - global_volume = global_vol; - linear_periods = module.linear_periods; - fast_volume_slides = module.fast_volume_slides; - current_note = new int[ 5 ]; - log_2_sampling_rate = LogTable.log_2( sampling_rate ); - } - - public void reset() { - tremolo_speed = 0; - tremolo_depth = 0; - tremolo_wave = 0; - vibrato_speed = 0; - vibrato_depth = 0; - vibrato_wave = 0; - volume_slide_param = 0; - portamento_param = 0; - retrig_param = 0; - random_seed = 0xABC123; - instrument = module.get_instrument( 0 ); - row( 48, 256, 0, 0, 0 ); - } - - public void resample( int[] mixing_buffer, int frame_offset, int frames, int quality ) { - if( !silent ) { - switch( quality ) { - default: - sample.resample_nearest( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames ); - break; - case 1: - sample.resample_linear( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames ); - break; - case 2: - sample.resample_sinc( sample_idx, sample_frac, step, left_gain, right_gain, mixing_buffer, frame_offset, frames ); - break; - } - } - } - - public void update_sample_idx( int samples ) { - sample_frac += step * samples; - sample_idx += sample_frac >> IBXM.FP_SHIFT; - sample_frac &= IBXM.FP_MASK; - } - - public void set_volume( int vol ) { - if( vol < 0 ) { - vol = 0; - } - if( vol > 64 ) { - vol = 64; - } - volume = vol; - } - - public void set_panning( int pan ) { - if( pan < 0 ) { - pan = 0; - } - if( pan > 255 ) { - pan = 255; - } - panning = pan; - } - - public void row( int key, int inst_idx, int volume_column, int effect, int effect_param ) { - effect = effect & 0xFF; - if( effect >= 0x30 ) { - /* Effects above 0x30 are internal.*/ - effect = 0; - } - if( effect == 0x00 && effect_param != 0 ) { - /* Arpeggio.*/ - effect = 0x40; - } - if( effect == 0x0E ) { - /* Renumber 0x0Ex effect command.*/ - effect = 0x30 + ( ( effect_param & 0xF0 ) >> 4 ); - effect_param = effect_param & 0x0F; - } - if( effect == 0x21 ) { - /* Renumber 0x21x effect command.*/ - effect = 0x40 + ( ( effect_param & 0xF0 ) >> 4 ); - effect_param = effect_param & 0x0F; - } - current_note[ 0 ] = key; - current_note[ 1 ] = inst_idx; - current_note[ 2 ] = volume_column; - current_note[ 3 ] = effect; - current_note[ 4 ] = effect_param; - effect_tick = 0; - trigger_tick += 1; - update_envelopes(); - key_add = 0; - vibrato_add = 0; - tremolo_add = 0; - if( ! ( effect == 0x3D && effect_param > 0 ) ) { - /* Not note delay.*/ - trigger( key, inst_idx, volume_column, effect ); - /* Handle volume column.*/ - switch( volume_column & 0xF0 ) { - case 0x00: - /* Do nothing.*/ - break; - case 0x60: - /* Volume slide down.*/ - break; - case 0x70: - /* Volume slide up.*/ - break; - case 0x80: - /* Fine volume slide down.*/ - set_volume( volume - ( volume_column & 0x0F ) ); - break; - case 0x90: - /* Fine volume slide up.*/ - set_volume( volume + ( volume_column & 0x0F ) ); - break; - case 0xA0: - /* Set vibrato speed.*/ - set_vibrato_speed( volume_column & 0x0F ); - break; - case 0xB0: - /* Vibrato.*/ - set_vibrato_depth( volume_column & 0x0F ); - vibrato(); - break; - case 0xC0: - /* Set panning.*/ - set_panning( ( volume_column & 0x0F ) << 4 ); - break; - case 0xD0: - /* Panning slide left.*/ - break; - case 0xE0: - /* Panning slide right.*/ - break; - case 0xF0: - /* Tone portamento.*/ - set_portamento_param( volume_column & 0x0F ); - break; - default: - /* Set volume.*/ - set_volume( volume_column - 0x10 ); - break; - } - } - if( instrument.vibrato_depth > 0 ) { - auto_vibrato(); - } - switch( effect ) { - case 0x01: - /* Portmento Up.*/ - set_portamento_param( effect_param ); - portamento_up(); - break; - case 0x02: - /* Portamento Down.*/ - set_portamento_param( effect_param ); - portamento_down(); - break; - case 0x03: - /* Tone Portamento.*/ - set_portamento_param( effect_param ); - break; - case 0x04: - /* Vibrato.*/ - set_vibrato_speed( ( effect_param & 0xF0 ) >> 4 ); - set_vibrato_depth( effect_param & 0x0F ); - vibrato(); - break; - case 0x05: - /* Tone Portamento + Volume Slide.*/ - set_volume_slide_param( effect_param ); - volume_slide(); - break; - case 0x06: - /* Vibrato + Volume Slide.*/ - set_volume_slide_param( effect_param ); - vibrato(); - volume_slide(); - break; - case 0x07: - /* Tremolo.*/ - set_tremolo_speed( ( effect_param & 0xF0 ) >> 4 ); - set_tremolo_depth( effect_param & 0x0F ); - tremolo(); - break; - case 0x08: - /* Set Panning.*/ - set_panning( effect_param ); - break; - case 0x09: - /* Set Sample Index.*/ - set_sample_index( effect_param << 8 ); - break; - case 0x0A: - /* Volume Slide.*/ - set_volume_slide_param( effect_param ); - volume_slide(); - break; - case 0x0B: - /* Pattern Jump.*/ - break; - case 0x0C: - /* Set volume.*/ - set_volume( effect_param ); - break; - case 0x0D: - /* Pattern Break.*/ - break; - case 0x0E: - /* Extended Commands (See 0x30-0x3F).*/ - break; - case 0x0F: - /* Set Speed/Tempo.*/ - break; - case 0x10: - /* Set Global Volume.*/ - set_global_volume( effect_param ); - break; - case 0x11: - /* global Volume Slide.*/ - set_volume_slide_param( effect_param ); - break; - case 0x14: - /* Key Off*/ - if( effect_param == 0 ) { - key_on = false; - } - break; - case 0x15: - /* Set Envelope Tick.*/ - set_envelope_tick( effect_param ); - break; - case 0x19: - /* Panning Slide.*/ - set_volume_slide_param( effect_param ); - break; - case 0x1B: - /* Retrig + Volume Slide.*/ - set_retrig_param( effect_param ); - retrig_volume_slide(); - break; - case 0x1D: - /* Tremor.*/ - set_retrig_param( effect_param ); - tremor(); - break; - case 0x24: - /* S3M Fine Vibrato.*/ - set_vibrato_speed( ( effect_param & 0xF0 ) >> 4 ); - set_vibrato_depth( effect_param & 0x0F ); - fine_vibrato(); - break; - case 0x25: - /* S3M Set Speed.*/ - break; - case 0x30: - /* Amiga Set Filter.*/ - break; - case 0x31: - /* Fine Portamento Up.*/ - set_portamento_param( 0xF0 | effect_param ); - portamento_up(); - break; - case 0x32: - /* Fine Portamento Down.*/ - set_portamento_param( 0xF0 | effect_param ); - portamento_down(); - break; - case 0x33: - /* Set Glissando Mode.*/ - break; - case 0x34: - /* Set Vibrato Waveform.*/ - set_vibrato_wave( effect_param ); - break; - case 0x35: - /* Set Fine Tune.*/ - break; - case 0x36: - /* Pattern Loop.*/ - break; - case 0x37: - /* Set Tremolo Waveform.*/ - set_tremolo_wave( effect_param ); - break; - case 0x38: - /* Set Panning(Obsolete).*/ - break; - case 0x39: - /* Retrig.*/ - set_retrig_param( effect_param ); - break; - case 0x3A: - /* Fine Volume Slide Up.*/ - set_volume_slide_param( ( effect_param << 4 ) | 0x0F ); - volume_slide(); - break; - case 0x3B: - /* Fine Volume Slide Down.*/ - set_volume_slide_param( 0xF0 | effect_param ); - volume_slide(); - break; - case 0x3C: - /* Note Cut.*/ - if( effect_param == 0 ) { - set_volume( 0 ); - } - break; - case 0x3D: - /* Note Delay.*/ - break; - case 0x3E: - /* Pattern Delay.*/ - break; - case 0x3F: - /* Invert Loop.*/ - break; - case 0x40: - /* Arpeggio.*/ - break; - case 0x41: - /* Extra Fine Porta Up.*/ - set_portamento_param( 0xE0 | effect_param ); - portamento_up(); - break; - case 0x42: - /* Extra Fine Porta Down.*/ - set_portamento_param( 0xE0 | effect_param ); - portamento_down(); - break; - } - calculate_amplitude(); - calculate_frequency(); - } - - public void tick() { - int volume_column, effect, effect_param; - volume_column = current_note[ 2 ]; - effect = current_note[ 3 ]; - effect_param = current_note[ 4 ]; - effect_tick += 1; - if( effect == 0x3D && effect_param == effect_tick ) { - /* Note delay.*/ - row( current_note[ 0 ], current_note[ 1 ], volume_column, 0, 0 ); - } else { - trigger_tick += 1; - vibrato_tick += 1; - tremolo_tick += 1; - update_envelopes(); - key_add = 0; - vibrato_add = 0; - tremolo_add = 0; - if( instrument.vibrato_depth > 0 ) { - auto_vibrato(); - } - switch( volume_column & 0xF0 ) { - case 0x60: - /* Volume Slide Down.*/ - set_volume( volume - ( volume_column & 0x0F ) ); - break; - case 0x70: - /* Volume Slide Up.*/ - set_volume( volume + ( volume_column & 0x0F ) ); - break; - case 0xB0: - /* Vibrato.*/ - vibrato(); - break; - case 0xD0: - /* Panning Slide Left.*/ - set_panning( panning - ( volume_column & 0x0F ) ); - break; - case 0xE0: - /* Panning Slide Right.*/ - set_panning( panning + ( volume_column & 0x0F ) ); - break; - case 0xF0: - /* Tone Portamento.*/ - tone_portamento(); - break; - } - switch( effect ) { - case 0x01: - /* Portamento Up.*/ - portamento_up(); - break; - case 0x02: - /* Portamento Down.*/ - portamento_down(); - break; - case 0x03: - /* Tone Portamento.*/ - tone_portamento(); - break; - case 0x04: - /* Vibrato.*/ - vibrato(); - break; - case 0x05: - /* Tone Portamento + Volume Slide.*/ - tone_portamento(); - volume_slide(); - break; - case 0x06: - /* Vibrato + Volume Slide */ - vibrato(); - volume_slide(); - break; - case 0x07: - /* Tremolo.*/ - tremolo(); - break; - case 0x0A: - /* Volume Slide.*/ - volume_slide(); - break; - case 0x11: - /* Global Volume Slide.*/ - global_volume_slide(); - break; - case 0x14: - /* Key off.*/ - if( effect_tick == effect_param ) { - key_on = false; - } - break; - case 0x19: - /* Panning Slide.*/ - panning_slide(); - break; - case 0x1B: - /* Retrig + Volume Slide.*/ - retrig_volume_slide(); - break; - case 0x1D: - /* Tremor.*/ - tremor(); - break; - case 0x24: - /* S3M Fine Vibrato.*/ - fine_vibrato(); - break; - case 0x39: - /* Retrig.*/ - retrig_volume_slide(); - break; - case 0x3C: - /* Note Cut.*/ - if( effect_tick == effect_param ) { - set_volume( 0 ); - } - break; - case 0x40: - /* Arpeggio.*/ - switch( effect_tick % 3 ) { - case 1: - key_add = ( effect_param & 0xF0 ) >> 4; - break; - case 2: - key_add = effect_param & 0x0F; - break; - } - break; - } - } - calculate_amplitude(); - calculate_frequency(); - } - - private void set_vibrato_speed( int speed ) { - if( speed > 0 ) { - vibrato_speed = speed; - } - } - - private void set_vibrato_depth( int depth ) { - if( depth > 0 ) { - vibrato_depth = depth; - } - } - - private void set_vibrato_wave( int wave ) { - if( wave < 0 || wave > 7 ) { - wave = 0; - } - vibrato_wave = wave; - } - - private void set_tremolo_speed( int speed ) { - if( speed > 0 ) { - tremolo_speed = speed; - } - } - - private void set_tremolo_depth( int depth ) { - if( depth > 0 ) { - tremolo_depth = depth; - } - } - - private void set_tremolo_wave( int wave ) { - if( wave < 0 || wave > 7 ) { - wave = 0; - } - tremolo_wave = wave; - } - - private void vibrato() { - int vibrato_phase; - vibrato_phase = vibrato_tick * vibrato_speed; - vibrato_add += waveform( vibrato_phase, vibrato_wave ) * vibrato_depth >> 5; - } - - private void fine_vibrato() { - int vibrato_phase; - vibrato_phase = vibrato_tick * vibrato_speed; - vibrato_add += waveform( vibrato_phase, vibrato_wave ) * vibrato_depth >> 7; - } - - private void tremolo() { - int tremolo_phase; - tremolo_phase = tremolo_tick * tremolo_speed; - tremolo_add += waveform( tremolo_phase, tremolo_wave ) * tremolo_depth >> 6; - } - - private void set_portamento_param( int param ) { - if( param != 0 ) { - portamento_param = param; - } - } - - private void tone_portamento() { - int new_period; - if( porta_period < period ) { - new_period = period - ( portamento_param << 2 ); - if( new_period < porta_period ) { - new_period = porta_period; - } - set_period( new_period ); - } - if( porta_period > period ) { - new_period = period + ( portamento_param << 2 ); - if( new_period > porta_period ) { - new_period = porta_period; - } - set_period( new_period ); - } - } - - private void portamento_up() { - if( ( portamento_param & 0xF0 ) == 0xE0 ) { - /* Extra-fine porta.*/ - if( effect_tick == 0 ) { - set_period( period - ( portamento_param & 0x0F ) ); - } - } else if( ( portamento_param & 0xF0 ) == 0xF0 ) { - /* Fine porta.*/ - if( effect_tick == 0 ) { - set_period( period - ( ( portamento_param & 0x0F ) << 2 ) ); - } - } else { - /* Normal porta.*/ - if( effect_tick > 0 ) { - set_period( period - ( portamento_param << 2 ) ); - } - } - } - - private void portamento_down() { - if( ( portamento_param & 0xF0 ) == 0xE0 ) { - /* Extra-fine porta.*/ - if( effect_tick == 0 ) { - set_period( period + ( portamento_param & 0x0F ) ); - } - } else if( ( portamento_param & 0xF0 ) == 0xF0 ) { - /* Fine porta.*/ - if( effect_tick == 0 ) { - set_period( period + ( ( portamento_param & 0x0F ) << 2 ) ); - } - } else { - /* Normal porta.*/ - if( effect_tick > 0 ) { - set_period( period + ( portamento_param << 2 ) ); - } - } - } - - private void set_period( int p ) { - if( p < 32 ) { - p = 32; - } - if( p > 32768 ) { - p = 32768; - } - period = p; - } - - private void set_global_volume( int vol ) { - if( vol < 0 ) { - vol = 0; - } - if( vol > 64 ) { - vol = 64; - } - global_volume[ 0 ] = vol; - } - - private void set_volume_slide_param( int param ) { - if( param != 0 ) { - volume_slide_param = param; - } - } - - private void global_volume_slide() { - int up, down; - up = ( volume_slide_param & 0xF0 ) >> 4; - down = volume_slide_param & 0x0F; - set_global_volume( global_volume[ 0 ] + up - down ); - } - - private void volume_slide() { - int up, down; - up = ( volume_slide_param & 0xF0 ) >> 4; - down = volume_slide_param & 0x0F; - if( down == 0x0F && up > 0 ) { - /* Fine slide up.*/ - if( effect_tick == 0 ) { - set_volume( volume + up ); - } - } else if( up == 0x0F && down > 0 ) { - /* Fine slide down.*/ - if( effect_tick == 0 ) { - set_volume( volume - down ); - } - } else { - /* Normal slide.*/ - if( effect_tick > 0 || fast_volume_slides ) { - set_volume( volume + up - down ); - } - } - } - - private void panning_slide() { - int left, right; - left = ( volume_slide_param & 0xF0 ) >> 4; - right = volume_slide_param & 0x0F; - set_panning( panning - left + right ); - } - - private void set_retrig_param( int param ) { - if( param != 0 ) { - retrig_param = param; - } - } - - private void tremor() { - int on_ticks, cycle_length, cycle_index; - on_ticks = ( ( retrig_param & 0xF0 ) >> 4 ) + 1; - cycle_length = on_ticks + ( retrig_param & 0x0F ) + 1; - cycle_index = trigger_tick % cycle_length; - if( cycle_index >= on_ticks ) { - tremolo_add = -64; - } - } - - private void retrig_volume_slide() { - int retrig_volume, retrig_tick; - retrig_volume = ( retrig_param & 0xF0 ) >> 4; - retrig_tick = retrig_param & 0x0F; - if( retrig_tick > 0 && ( trigger_tick % retrig_tick ) == 0 ) { - set_sample_index( 0 ); - switch( retrig_volume ) { - case 0x01: - set_volume( volume - 1 ); - break; - case 0x02: - set_volume( volume - 2 ); - break; - case 0x03: - set_volume( volume - 4 ); - break; - case 0x04: - set_volume( volume - 8 ); - break; - case 0x05: - set_volume( volume - 16 ); - break; - case 0x06: - set_volume( volume - volume / 3 ); - break; - case 0x07: - set_volume( volume / 2 ); - break; - case 0x09: - set_volume( volume + 1 ); - break; - case 0x0A: - set_volume( volume + 2 ); - break; - case 0x0B: - set_volume( volume + 4 ); - break; - case 0x0C: - set_volume( volume + 8 ); - break; - case 0x0D: - set_volume( volume + 16 ); - break; - case 0x0E: - set_volume( volume + volume / 2 ); - break; - case 0x0F: - set_volume( volume * 2 ); - break; - } - } - } - - private void set_sample_index( int index ) { - if( index < 0 ) { - index = 0; - } - sample_idx = index; - sample_frac = 0; - } - - private void set_envelope_tick( int tick ) { - volume_envelope_tick = tick; - panning_envelope_tick = tick; - } - - private void trigger( int key, int instrument_idx, int volume_column, int effect ) { - if( instrument_idx > 0 ) { - instrument = module.get_instrument( instrument_idx ); - sample = instrument.get_sample_from_key( key ); - set_volume( sample.volume ); - if( sample.set_panning ) { - set_panning( sample.panning ); - } - set_envelope_tick( 0 ); - fade_out_volume = 32768; - key_on = true; - } - if( key > 0 ) { - if( key < 97 ) { - porta_period = key_to_period( key ); - if( effect != 0x03 && effect != 0x05 ) { - if( ( volume_column & 0xF0 ) != 0xF0 ) { - /* Not portamento.*/ - trigger_tick = 0; - if( vibrato_wave < 4 ) { - vibrato_tick = 0; - } - if( tremolo_wave < 4 ) { - tremolo_tick = 0; - } - set_period( porta_period ); - set_sample_index( 0 ); - } - } - } else { - /* Key off.*/ - key_on = false; - } - } - } - - private void update_envelopes() { - Envelope envelope; - if( instrument.volume_envelope_active ) { - if( !key_on ) { - fade_out_volume -= instrument.volume_fade_out & 0xFFFF; - if( fade_out_volume < 0 ) { - fade_out_volume = 0; - } - } - envelope = instrument.get_volume_envelope(); - volume_envelope_tick = envelope.next_tick( volume_envelope_tick, key_on ); - } - if( instrument.panning_envelope_active ) { - envelope = instrument.get_panning_envelope(); - panning_envelope_tick = envelope.next_tick( panning_envelope_tick, key_on ); - } - } - - private void auto_vibrato() { - int sweep, depth, rate; - sweep = instrument.vibrato_sweep & 0xFF; - depth = instrument.vibrato_depth & 0x0F; - rate = instrument.vibrato_rate & 0x3F; - if( trigger_tick < sweep ) { - depth = depth * trigger_tick / sweep; - } - vibrato_add += waveform( trigger_tick * rate, 0 ) * depth >> 9; - } - - private int waveform( int phase, int wform ) { - int amplitude; - amplitude = 0; - switch( wform & 0x3 ) { - case 0: - /* Sine. */ - if( ( phase & 0x20 ) == 0 ) { - amplitude = sine_table[ phase & 0x1F ]; - } else { - amplitude = -sine_table[ phase & 0x1F ]; - } - break; - case 1: - /* Saw. */ - if( ( phase & 0x20 ) == 0 ) { - amplitude = ( phase & 0x1F ) << 3; - } else { - amplitude = ( ( phase & 0x1F ) << 3 ) - 255; - } - break; - case 2: - /* Square. */ - if( ( phase & 0x20 ) == 0 ) { - amplitude = 255; - } else { - amplitude = -255; - } - break; - case 3: - /* Random. */ - amplitude = ( random_seed >> 15 ) - 255; - random_seed = ( random_seed * 65 + 17 ) & 0xFFFFFF; - break; - } - return amplitude; - } - - private int key_to_period( int key ) { - int octave, log_2_period, period_out; - octave = ( key << IBXM.FP_SHIFT ) / 12 + sample.transpose; - if( linear_periods ) { - period_out = 7744 - ( octave * 768 >> IBXM.FP_SHIFT ); - } else { - log_2_period = LOG_2_29024 - octave; - period_out = LogTable.raise_2( log_2_period ); - period_out = period_out >> ( IBXM.FP_SHIFT - 1 ); - period_out = ( period_out >> 1 ) + ( period_out & 1 ); - } - return period_out; - } - - private void calculate_amplitude() { - int envelope_volume, tremolo_volume, amplitude; - int envelope_panning, mixer_panning, panning_range; - Envelope envelope; - envelope_volume = 0; - if( instrument.volume_envelope_active ) { - envelope = instrument.get_volume_envelope(); - envelope_volume = envelope.calculate_ampl( volume_envelope_tick ); - } else { - if( key_on ) { - envelope_volume = 64; - } - } - tremolo_volume = volume + tremolo_add; - if( tremolo_volume < 0 ) { - tremolo_volume = 0; - } - if( tremolo_volume > 64 ) { - tremolo_volume = 64; - } - amplitude = tremolo_volume << IBXM.FP_SHIFT - 6; - amplitude = amplitude * envelope_volume >> 6; - amplitude = amplitude * fade_out_volume >> 15; - amplitude = amplitude * global_volume[ 0 ] >> 6; - amplitude = amplitude * module.channel_gain >> IBXM.FP_SHIFT; - silent = sample.has_finished( sample_idx ); - if( amplitude <= 0 ) { - silent = true; - } else { - envelope_panning = 32; - if( instrument.panning_envelope_active ) { - envelope = instrument.get_panning_envelope(); - envelope_panning = envelope.calculate_ampl( panning_envelope_tick ); - } - mixer_panning = ( panning & 0xFF ) << IBXM.FP_SHIFT - 8; - panning_range = IBXM.FP_ONE - mixer_panning; - if( panning_range > mixer_panning ) { - panning_range = mixer_panning; - } - mixer_panning = mixer_panning + ( panning_range * ( envelope_panning - 32 ) >> 5 ); - left_gain = amplitude * ( IBXM.FP_ONE - mixer_panning ) >> IBXM.FP_SHIFT; - right_gain = amplitude * mixer_panning >> IBXM.FP_SHIFT; - } - } - - private void calculate_frequency() { - int vibrato_period, log_2_freq; - vibrato_period = period + vibrato_add; - if( vibrato_period < 32 ) { - vibrato_period = 32; - } - if( vibrato_period > 32768 ) { - vibrato_period = 32768; - } - if( linear_periods ) { - log_2_freq = LOG_2_8363 + ( 4608 - vibrato_period << IBXM.FP_SHIFT ) / 768; - } else { - log_2_freq = module.pal ? LOG_2_8287 : LOG_2_8363; - log_2_freq = log_2_freq + LOG_2_1712 - LogTable.log_2( vibrato_period ); - } - log_2_freq += ( key_add << IBXM.FP_SHIFT ) / 12; - step = LogTable.raise_2( log_2_freq - log_2_sampling_rate ); - } -} - diff --git a/src/main/java/ibxm/Envelope.java b/src/main/java/ibxm/Envelope.java deleted file mode 100644 index 6282d8355..000000000 --- a/src/main/java/ibxm/Envelope.java +++ /dev/null @@ -1,111 +0,0 @@ - -package ibxm; - -public class Envelope { - public boolean sustain, looped; - private int sustain_tick, loop_start_tick, loop_end_tick; - private int[] ticks, ampls; - - public Envelope() { - set_num_points( 1 ); - } - - public void set_num_points( int num_points ) { - //int point; Forge: Unused - if( num_points <= 0 ) { - num_points = 1; - } - ticks = new int[ num_points ]; - ampls = new int[ num_points ]; - set_point( 0, 0, 0, false ); - } - - /* When you set a point, all subsequent points are reset. */ - public void set_point( int point, int tick, int ampl, boolean delta ) { - if( point >= 0 && point < ticks.length ) { - if( point == 0 ) { - tick = 0; - } - if( point > 0 ) { - if( delta ) tick += ticks[ point - 1 ]; - if( tick <= ticks[ point - 1 ] ) { - System.out.println( "Envelope: Point not valid (" + tick + " <= " + ticks[ point - 1 ] + ")"); - tick = ticks[ point - 1 ] + 1; - } - } - ticks[ point ] = tick; - ampls[ point ] = ampl; - point += 1; - while( point < ticks.length ) { - ticks[ point ] = ticks[ point - 1 ] + 1; - ampls[ point ] = 0; - point += 1; - } - } - } - - public void set_sustain_point( int point ) { - if( point < 0 ) { - point = 0; - } - if( point >= ticks.length ) { - point = ticks.length - 1; - } - sustain_tick = ticks[ point ]; - } - - public void set_loop_points( int start, int end ) { - if( start < 0 ) { - start = 0; - } - if( start >= ticks.length ) { - start = ticks.length - 1; - } - if( end < start || end >= ticks.length ) { - end = start; - } - loop_start_tick = ticks[ start ]; - loop_end_tick = ticks[ end ]; - } - - public int next_tick( int tick, boolean key_on ) { - tick = tick + 1; - if( looped && tick >= loop_end_tick ) { - tick = loop_start_tick; - } - if( sustain && key_on && tick >= sustain_tick ) { - tick = sustain_tick; - } - return tick; - } - - public int calculate_ampl( int tick ) { - int idx, point, delta_t, delta_a, ampl; - ampl = ampls[ ticks.length - 1 ]; - if( tick < ticks[ ticks.length - 1 ] ) { - point = 0; - for( idx = 1; idx < ticks.length; idx++ ) { - if( ticks[ idx ] <= tick ) { - point = idx; - } - } - delta_t = ticks[ point + 1 ] - ticks[ point ]; - delta_a = ampls[ point + 1 ] - ampls[ point ]; - ampl = ( delta_a << IBXM.FP_SHIFT ) / delta_t; - ampl = ampl * ( tick - ticks[ point ] ) >> IBXM.FP_SHIFT; - ampl = ampl + ampls[ point ]; - } - return ampl; - } - - public void dump() { - int idx, tick; - for( idx = 0; idx < ticks.length; idx++ ) { - System.out.println( ticks[ idx ] + ", " + ampls[ idx ] ); - } - for( tick = 0; tick < 222; tick++ ) { - System.out.print( calculate_ampl( tick ) + ", " ); - } - } -} - diff --git a/src/main/java/ibxm/FastTracker2.java b/src/main/java/ibxm/FastTracker2.java deleted file mode 100644 index 2249bfffe..000000000 --- a/src/main/java/ibxm/FastTracker2.java +++ /dev/null @@ -1,257 +0,0 @@ - -package ibxm; - -import java.io.*; - -public class FastTracker2 { - public static boolean is_xm( byte[] header_60_bytes ) { - String xm_identifier; - xm_identifier = ascii_text( header_60_bytes, 0, 17 ); - return xm_identifier.equals( "Extended Module: " ); - } - - public static Module load_xm( byte[] header_60_bytes, DataInput data_input ) throws IOException { - int xm_version, song_header_length, sequence_length; - int num_channels, num_patterns, num_instruments, xm_flags, idx; - byte[] structure_header, song_header; - boolean delta_env; - String tracker_name; - Instrument instrument; - Module module; - if( !is_xm( header_60_bytes ) ) { - throw new IllegalArgumentException( "Not an XM file!" ); - } - xm_version = unsigned_short_le( header_60_bytes, 58 ); - if( xm_version != 0x0104 ) { - throw new IllegalArgumentException( "Sorry, XM version " + xm_version + " is not supported!" ); - } - module = new Module(); - module.song_title = ascii_text( header_60_bytes, 17, 20 ); - tracker_name = ascii_text( header_60_bytes, 38, 20 ); - delta_env = tracker_name.startsWith( "DigiBooster Pro" ); - structure_header = new byte[ 4 ]; - data_input.readFully( structure_header ); - song_header_length = int_le( structure_header, 0 ); - song_header = new byte[ song_header_length ]; - data_input.readFully( song_header, 4, song_header_length - 4 ); - sequence_length = unsigned_short_le( song_header, 4 ); - module.restart_sequence_index = unsigned_short_le( song_header, 6 ); - num_channels = unsigned_short_le( song_header, 8 ); - num_patterns = unsigned_short_le( song_header, 10 ); - num_instruments = unsigned_short_le( song_header, 12 ); - xm_flags = unsigned_short_le( song_header, 14 ); - module.linear_periods = ( xm_flags & 0x1 ) == 0x1; - module.global_volume = 64; - module.channel_gain = IBXM.FP_ONE * 3 / 8; - module.default_speed = unsigned_short_le( song_header, 16 ); - module.default_tempo = unsigned_short_le( song_header, 18 ); - module.set_num_channels( num_channels ); - for( idx = 0; idx < num_channels; idx++ ) { - module.set_initial_panning( idx, 128 ); - } - module.set_sequence_length( sequence_length ); - for( idx = 0; idx < sequence_length; idx++ ) { - module.set_sequence( idx, song_header[ 20 + idx ] & 0xFF ); - } - module.set_num_patterns( num_patterns ); - for( idx = 0; idx < num_patterns; idx++ ) { - module.set_pattern( idx, read_xm_pattern( data_input, num_channels ) ); - } - module.set_num_instruments( num_instruments ); - for( idx = 1; idx <= num_instruments; idx++ ) { - try { - instrument = read_xm_instrument( data_input, delta_env ); - module.set_instrument( idx, instrument ); - } catch( EOFException e ) { - System.out.println( "Instrument " + idx + " is missing!" ); - } - } - return module; - } - - private static Pattern read_xm_pattern( DataInput data_input, int num_channels ) throws IOException { - @SuppressWarnings("unused") //Forge - int pattern_header_length, packing_type, num_rows, pattern_data_length; - byte[] structure_header, pattern_header, pattern_data; - Pattern pattern; - structure_header = new byte[ 4 ]; - data_input.readFully( structure_header ); - pattern_header_length = int_le( structure_header, 0 ); - pattern_header = new byte[ pattern_header_length ]; - data_input.readFully( pattern_header, 4, pattern_header_length - 4 ); - packing_type = pattern_header[ 4 ]; - if( packing_type != 0 ) { - throw new IllegalArgumentException( "Pattern packing type " + packing_type + " is not supported!" ); - } - pattern = new Pattern(); - pattern.num_rows = unsigned_short_le( pattern_header, 5 ); - pattern_data_length = unsigned_short_le( pattern_header, 7 ); - pattern_data = new byte[ pattern_data_length ]; - data_input.readFully( pattern_data ); - pattern.set_pattern_data( pattern_data ); - return pattern; - } - - private static Instrument read_xm_instrument( DataInput data_input, boolean delta_env ) throws IOException { - int instrument_header_length, num_samples, idx; - int env_tick, env_ampl, env_num_points, flags; - byte[] structure_header, instrument_header, sample_headers; - Instrument instrument; - Envelope envelope; - structure_header = new byte[ 4 ]; - data_input.readFully( structure_header ); - instrument_header_length = int_le( structure_header, 0 ); - instrument_header = new byte[ instrument_header_length ]; - data_input.readFully( instrument_header, 4, instrument_header_length - 4 ); - instrument = new Instrument(); - instrument.name = ascii_text( instrument_header, 4, 22 ); - num_samples = unsigned_short_le( instrument_header, 27 ); - if( num_samples > 0 ) { - instrument.set_num_samples( num_samples ); - for( idx = 0; idx < 96; idx++ ) { - instrument.set_key_to_sample( idx + 1, instrument_header[ 33 + idx ] & 0xFF ); - } - envelope = new Envelope(); - env_num_points = instrument_header[ 225 ] & 0xFF; - envelope.set_num_points( env_num_points ); - for( idx = 0; idx < env_num_points; idx++ ) { - env_tick = unsigned_short_le( instrument_header, 129 + idx * 4 ); - env_ampl = unsigned_short_le( instrument_header, 131 + idx * 4 ); - envelope.set_point( idx, env_tick, env_ampl, delta_env ); - } - envelope.set_sustain_point( instrument_header[ 227 ] & 0xFF ); - envelope.set_loop_points( instrument_header[ 228 ] & 0xFF, instrument_header[ 229 ] & 0xFF ); - flags = instrument_header[ 233 ] & 0xFF; - instrument.volume_envelope_active = ( flags & 0x1 ) == 0x1; - envelope.sustain = ( flags & 0x2 ) == 0x2; - envelope.looped = ( flags & 0x4 ) == 0x4; - instrument.set_volume_envelope( envelope ); - envelope = new Envelope(); - env_num_points = instrument_header[ 226 ] & 0xFF; - envelope.set_num_points( env_num_points ); - for( idx = 0; idx < env_num_points; idx++ ) { - env_tick = unsigned_short_le( instrument_header, 177 + idx * 4 ); - env_ampl = unsigned_short_le( instrument_header, 179 + idx * 4 ); - envelope.set_point( idx, env_tick, env_ampl, delta_env ); - } - envelope.set_sustain_point( instrument_header[ 230 ] & 0xFF ); - envelope.set_loop_points( instrument_header[ 231 ] & 0xFF, instrument_header[ 232 ] & 0xFF ); - flags = instrument_header[ 234 ] & 0xFF; - instrument.panning_envelope_active = ( flags & 0x1 ) == 0x1; - envelope.sustain = ( flags & 0x2 ) == 0x2; - envelope.looped = ( flags & 0x4 ) == 0x4; - instrument.set_panning_envelope( envelope ); - instrument.vibrato_type = instrument_header[ 235 ] & 0xFF; - instrument.vibrato_sweep = instrument_header[ 236 ] & 0xFF; - instrument.vibrato_depth = instrument_header[ 237 ] & 0xFF; - instrument.vibrato_rate = instrument_header[ 238 ] & 0xFF; - instrument.volume_fade_out = unsigned_short_le( instrument_header, 239 ); - sample_headers = new byte[ num_samples * 40 ]; - data_input.readFully( sample_headers ); - for( idx = 0; idx < num_samples; idx++ ) { - instrument.set_sample( idx, read_xm_sample( sample_headers, idx, data_input ) ); - } - } - return instrument; - } - - 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 flags, in_idx, out_idx, sam, last_sam; - int fine_tune, relative_note; - boolean sixteen_bit, ping_pong; - byte[] raw_sample_data; - short[] decoded_sample_data; - Sample sample; - header_offset = sample_idx * 40; - sample = new Sample(); - sample_length = int_le( sample_headers, header_offset ); - loop_start = int_le( sample_headers, header_offset + 4 ); - loop_length = int_le( sample_headers, header_offset + 8 ); - sample.volume = sample_headers[ header_offset + 12 ] & 0xFF; - fine_tune = sample_headers[ header_offset + 13 ]; - fine_tune = ( fine_tune << IBXM.FP_SHIFT ) / 1536; - sample.set_panning = true; - flags = sample_headers[ header_offset + 14 ] & 0xFF; - if( ( flags & 0x03 ) == 0 ) { - loop_length = 0; - } - ping_pong = ( flags & 0x02 ) == 0x02; - sixteen_bit = ( flags & 0x10 ) == 0x10; - sample.panning = sample_headers[ header_offset + 15 ] & 0xFF; - relative_note = sample_headers[ header_offset + 16 ]; - relative_note = ( relative_note << IBXM.FP_SHIFT ) / 12; - sample.transpose = relative_note + fine_tune; - sample.name = ascii_text( sample_headers, header_offset + 18, 22 ); - raw_sample_data = new byte[ sample_length ]; - try { - data_input.readFully( raw_sample_data ); - } catch( EOFException e ) { - System.out.println( "Sample has been truncated!" ); - } - in_idx = 0; - out_idx = 0; - sam = 0; - last_sam = 0; - if( sixteen_bit ) { - decoded_sample_data = new short[ sample_length >> 1 ]; - while( in_idx < raw_sample_data.length ) { - sam = raw_sample_data[ in_idx ] & 0xFF; - sam = sam | ( ( raw_sample_data[ in_idx + 1 ] & 0xFF ) << 8 ); - last_sam = last_sam + sam; - decoded_sample_data[ out_idx ] = ( short ) last_sam; - in_idx += 2; - out_idx += 1; - } - sample.set_sample_data( decoded_sample_data, loop_start >> 1, loop_length >> 1, ping_pong ); - } else { - decoded_sample_data = new short[ sample_length ]; - while( in_idx < raw_sample_data.length ) { - sam = raw_sample_data[ in_idx ] & 0xFF; - last_sam = last_sam + sam; - decoded_sample_data[ out_idx ] = ( short ) ( last_sam << 8 ); - in_idx += 1; - out_idx += 1; - } - sample.set_sample_data( decoded_sample_data, loop_start, loop_length, ping_pong ); - } - return sample; - } - - private static int unsigned_short_le( byte[] buffer, int offset ) { - int value; - value = buffer[ offset ] & 0xFF; - value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 ); - return value; - } - - private static int int_le( byte[] buffer, int offset ) { - int value; - value = buffer[ offset ] & 0xFF; - value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 ); - value = value | ( ( buffer[ offset + 2 ] & 0xFF ) << 16 ); - value = value | ( ( buffer[ offset + 3 ] & 0x7F ) << 24 ); - return value; - } - - private static String ascii_text( byte[] buffer, int offset, int length ) { - int idx, chr; - byte[] string_buffer; - String string; - string_buffer = new byte[ length ]; - for( idx = 0; idx < length; idx++ ) { - chr = buffer[ offset + idx ]; - if( chr < 32 ) { - chr = 32; - } - string_buffer[ idx ] = ( byte ) chr; - } - try { - string = new String( string_buffer, 0, length, "ISO-8859-1" ); - } catch( UnsupportedEncodingException e ) { - string = ""; - } - return string; - } -} - diff --git a/src/main/java/ibxm/IBXM.java b/src/main/java/ibxm/IBXM.java deleted file mode 100644 index 00f22a6aa..000000000 --- a/src/main/java/ibxm/IBXM.java +++ /dev/null @@ -1,343 +0,0 @@ - -package ibxm; - -public class IBXM { - 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_ONE = 1 << FP_SHIFT; - public static final int FP_MASK = FP_ONE - 1; - - private int sampling_rate, resampling_quality, volume_ramp_length; - private int tick_length_samples, current_tick_samples; - private int[] mixing_buffer, volume_ramp_buffer; - - private Module module; - private Channel[] channels; - private int[] global_volume, note; - private int current_sequence_index, next_sequence_index; - private int current_row, next_row; - private int tick_counter, ticks_per_row; - private int pattern_loop_count, pattern_loop_channel; - - public IBXM( int sample_rate ) { - -/** MODIFIED 13 Oct 2009 by Paul Lamb **/ -// System.out.println( VERSION ); -/***************************************/ - - if( sample_rate < 8000 ) { - sample_rate = 8000; - } - sampling_rate = sample_rate; - volume_ramp_length = sampling_rate >> 10; - volume_ramp_buffer = new int[ volume_ramp_length * 2 ]; - mixing_buffer = new int[ sampling_rate / 6 ]; - global_volume = new int[ 1 ]; - note = new int[ 5 ]; - set_module( new Module() ); - set_resampling_quality( 1 ); - } - - public void set_module( Module m ) { - int channel_idx; - module = m; - channels = new Channel[ module.get_num_channels() ]; - for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { - channels[ channel_idx ] = new Channel( module, sampling_rate, global_volume ); - } - set_sequence_index( 0, 0 ); - } - - public void set_resampling_quality( int quality ) { - resampling_quality = quality; - } - - public int calculate_song_duration() { - int song_duration; - set_sequence_index( 0, 0 ); - next_tick(); - song_duration = tick_length_samples; - while( !next_tick() ) { - song_duration += tick_length_samples; - } - set_sequence_index( 0, 0 ); - return song_duration; - } - - public void set_sequence_index( int sequence_index, int row ) { - int channel_idx; - global_volume[ 0 ] = 64; - for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { - channels[ channel_idx ].reset(); - channels[ channel_idx ].set_panning( module.get_initial_panning( channel_idx ) ); - } - set_global_volume( module.global_volume ); - set_speed( 6 ); - set_speed( module.default_speed ); - set_tempo( 125 ); - set_tempo( module.default_tempo ); - pattern_loop_count = -1; - next_sequence_index = sequence_index; - next_row = row; - tick_counter = 0; - current_tick_samples = tick_length_samples; - clear_vol_ramp_buffer(); - } - - public void seek( int sample_position ) { - //int idx; Forge, Unused - set_sequence_index( 0, 0 ); - next_tick(); - while( sample_position > tick_length_samples ) { - sample_position -= tick_length_samples; - next_tick(); - } - mix_tick(); - current_tick_samples = sample_position; - } - - public void get_audio( byte[] output_buffer, int frames ) { - int output_idx, mix_idx, mix_end, count, amplitude; - output_idx = 0; - while( frames > 0 ) { - count = tick_length_samples - current_tick_samples; - if( count > frames ) { - count = frames; - } - mix_idx = current_tick_samples << 1; - mix_end = mix_idx + ( count << 1 ) - 1; - while( mix_idx <= mix_end ) { - amplitude = mixing_buffer[ mix_idx ]; - if( amplitude > 32767 ) { - amplitude = 32767; - } - if( amplitude < -32768 ) { - amplitude = -32768; - } - output_buffer[ output_idx ] = ( byte ) ( amplitude >> 8 ); - output_buffer[ output_idx + 1 ] = ( byte ) ( amplitude & 0xFF ); - output_idx += 2; - mix_idx += 1; - } - current_tick_samples = mix_idx >> 1; - frames -= count; - if( frames > 0 ) { - next_tick(); - mix_tick(); - current_tick_samples = 0; - } - } - } - - private void mix_tick() { - int channel_idx, mix_idx, mix_len; - mix_idx = 0; - mix_len = tick_length_samples + volume_ramp_length << 1; - while( mix_idx < mix_len ) { - mixing_buffer[ mix_idx ] = 0; - mix_idx += 1; - } - for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { - mix_len = tick_length_samples + volume_ramp_length; - channels[ channel_idx ].resample( mixing_buffer, 0, mix_len, resampling_quality ); - } - volume_ramp(); - } - - private boolean next_tick() { - int channel_idx; - boolean song_end; - for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { - channels[ channel_idx ].update_sample_idx( tick_length_samples ); - } - tick_counter -= 1; - if( tick_counter <= 0 ) { - tick_counter = ticks_per_row; - song_end = next_row(); - } else { - for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { - channels[ channel_idx ].tick(); - } - song_end = false; - } - return song_end; - } - - private boolean next_row() { - int channel_idx, effect, effect_param; - boolean song_end; - Pattern pattern; - song_end = false; - if( next_sequence_index < 0 ) { - /* Bad next sequence index.*/ - next_sequence_index = 0; - next_row = 0; - } - if( next_sequence_index >= module.get_sequence_length() ) { - /* End of sequence.*/ - song_end = true; - next_sequence_index = module.restart_sequence_index; - if( next_sequence_index < 0 ) { - next_sequence_index = 0; - } - if( next_sequence_index >= module.get_sequence_length() ) { - next_sequence_index = 0; - } - next_row = 0; - } - if( next_sequence_index < current_sequence_index ) { - /* Jump to previous pattern. */ - song_end = true; - } - if( next_sequence_index == current_sequence_index ) { - if( next_row <= current_row ) { - if( pattern_loop_count < 0 ) { - /* Jump to previous row in the same pattern, but not a pattern loop. */ - song_end = true; - } - } - } - current_sequence_index = next_sequence_index; - pattern = module.get_pattern_from_sequence( current_sequence_index ); - if( next_row < 0 || next_row >= pattern.num_rows ) { - /* Bad next row.*/ - next_row = 0; - } - current_row = next_row; - next_row = current_row + 1; - if( next_row >= pattern.num_rows ) { - next_sequence_index = current_sequence_index + 1; - next_row = 0; - } - for( channel_idx = 0; channel_idx < channels.length; channel_idx++ ) { - pattern.get_note( note, current_row * channels.length + channel_idx ); - effect = note[ 3 ]; - effect_param = note[ 4 ]; - channels[ channel_idx ].row( note[ 0 ], note[ 1 ], note[ 2 ], effect, effect_param ); - switch( effect ) { - case 0x0B: - /* Pattern Jump.*/ - if( pattern_loop_count < 0 ) { - next_sequence_index = effect_param; - next_row = 0; - } - break; - case 0x0D: - /* Pattern Break.*/ - if( pattern_loop_count < 0 ) { - next_sequence_index = current_sequence_index + 1; - next_row = ( effect_param >> 4 ) * 10 + ( effect_param & 0x0F ); - } - break; - case 0x0E: - /* Extended.*/ - switch( effect_param & 0xF0 ) { - case 0x60: - /* Pattern loop.*/ - if( ( effect_param & 0x0F ) == 0 ) { - /* Set loop marker on this channel. */ - channels[ channel_idx ].pattern_loop_row = current_row; - } - if( channels[ channel_idx ].pattern_loop_row < current_row ) { - /* Marker and parameter are valid. Begin looping. */ - if( pattern_loop_count < 0 ) { - /* Not already looping, begin. */ - pattern_loop_count = effect_param & 0x0F; - pattern_loop_channel = channel_idx; - } - if( pattern_loop_channel == channel_idx ) { - /* Loop in progress on this channel. Next iteration. */ - if( pattern_loop_count == 0 ) { - /* Loop finished. */ - /* Invalidate current marker. */ - channels[ channel_idx ].pattern_loop_row = current_row + 1; - } else { - /* Count must be higher than zero. */ - /* Loop and cancel any breaks on this row. */ - next_row = channels[ channel_idx ].pattern_loop_row; - next_sequence_index = current_sequence_index; - } - pattern_loop_count -= 1; - } - } - break; - case 0xE0: - /* Pattern delay.*/ - tick_counter += ticks_per_row * ( effect_param & 0x0F ); - break; - } - break; - case 0x0F: - /* Set Speed/Tempo.*/ - if( effect_param < 32 ) { - set_speed( effect_param ); - tick_counter = ticks_per_row; - } else { - set_tempo( effect_param ); - } - break; - case 0x25: - /* S3M Set Speed.*/ - set_speed( effect_param ); - tick_counter = ticks_per_row; - break; - } - } - return song_end; - } - - private void set_global_volume( int volume ) { - if( volume < 0 ) { - volume = 0; - } - if( volume > 64 ) { - volume = 64; - } - global_volume[ 0 ] = volume; - } - - private void set_speed( int speed ) { - if( speed > 0 && speed < 256 ) { - ticks_per_row = speed; - } - } - - private void set_tempo( int bpm ) { - if( bpm > 31 && bpm < 256 ) { - tick_length_samples = ( sampling_rate * 5 ) / ( bpm * 2 ); - } - } - - private void volume_ramp() { - int ramp_idx, next_idx, ramp_end; - int volume_ramp_delta, volume, sample; - sample = 0; - volume_ramp_delta = FP_ONE / volume_ramp_length; - volume = 0; - ramp_idx = 0; - next_idx = 2 * tick_length_samples; - ramp_end = volume_ramp_length * 2 - 1; - while( ramp_idx <= ramp_end ) { - sample = volume_ramp_buffer[ ramp_idx ] * ( FP_ONE - 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 ]; - 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 ); - volume_ramp_buffer[ ramp_idx + 1 ] = mixing_buffer[ next_idx + ramp_idx + 1 ]; - volume += volume_ramp_delta; - ramp_idx += 2; - } - } - - private void clear_vol_ramp_buffer() { - int ramp_idx, ramp_end; - ramp_idx = 0; - ramp_end = volume_ramp_length * 2 - 1; - while( ramp_idx <= ramp_end ) { - volume_ramp_buffer[ ramp_idx ] = 0; - ramp_idx += 1; - } - } -} - diff --git a/src/main/java/ibxm/Instrument.java b/src/main/java/ibxm/Instrument.java deleted file mode 100644 index 074d27b5c..000000000 --- a/src/main/java/ibxm/Instrument.java +++ /dev/null @@ -1,90 +0,0 @@ - -package ibxm; - -public class Instrument { - public String name; - public int vibrato_type, vibrato_sweep; - public int vibrato_depth, vibrato_rate; - public boolean volume_envelope_active, panning_envelope_active; - public int volume_fade_out; - - private Envelope volume_envelope, panning_envelope; - private int[] key_to_sample; - private Sample[] samples; - - public Instrument() { - name = ""; - set_volume_envelope( new Envelope() ); - set_panning_envelope( new Envelope() ); - key_to_sample = new int[ 96 ]; - set_num_samples( 1 ); - } - - public Envelope get_volume_envelope() { - return volume_envelope; - } - - public void set_volume_envelope( Envelope envelope ) { - if( envelope != null ) { - volume_envelope = envelope; - } - } - - public Envelope get_panning_envelope() { - return panning_envelope; - } - - public void set_panning_envelope( Envelope envelope ) { - if( envelope != null ) { - panning_envelope = envelope; - } - } - - public Sample get_sample_from_key( int key ) { - int sample_idx; - sample_idx = 0; - if( key > 0 && key <= key_to_sample.length ) { - sample_idx = key_to_sample[ key - 1 ]; - } - return get_sample( sample_idx ); - } - - public void set_key_to_sample( int key, int sample ) { - if( key > 0 && key <= key_to_sample.length ) { - key_to_sample[ key - 1 ] = sample; - } - } - - public int get_num_samples() { - return samples.length; - } - - public void set_num_samples( int num_samples ) { - if( num_samples < 1 ) { - num_samples = 1; - } - samples = new Sample[ num_samples ]; - set_sample( 0, null ); - } - - public Sample get_sample( int sample_index ) { - Sample sample; - sample = null; - if( sample_index >= 0 && sample_index < samples.length ) { - sample = samples[ sample_index ]; - } - if( sample == null ) { - sample = samples[ 0 ]; - } - return sample; - } - - public void set_sample( int sample_index, Sample sample ) { - if( sample_index >= 0 && sample_index < samples.length ) { - samples[ sample_index ] = sample; - } - if( samples[ 0 ] == null ) { - samples[ 0 ] = new Sample(); - } - } -} diff --git a/src/main/java/ibxm/LogTable.java b/src/main/java/ibxm/LogTable.java deleted file mode 100644 index 7ace0f42c..000000000 --- a/src/main/java/ibxm/LogTable.java +++ /dev/null @@ -1,91 +0,0 @@ - -package ibxm; - -/* - Base-2 Log and Exp functions, using linear-interpolated tables. -*/ -public class LogTable { - 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_MASK = ( 1 << INTERP_SHIFT ) - 1; - - private static final int[] exp_2_table = { - 32768, 32945, 33124, 33304, 33485, 33667, 33850, 34033, - 34218, 34404, 34591, 34779, 34968, 35157, 35348, 35540, - 35733, 35927, 36122, 36319, 36516, 36714, 36913, 37114, - 37315, 37518, 37722, 37926, 38132, 38339, 38548, 38757, - 38967, 39179, 39392, 39606, 39821, 40037, 40254, 40473, - 40693, 40914, 41136, 41359, 41584, 41810, 42037, 42265, - 42494, 42725, 42957, 43190, 43425, 43661, 43898, 44136, - 44376, 44617, 44859, 45103, 45347, 45594, 45841, 46090, - 46340, 46592, 46845, 47099, 47355, 47612, 47871, 48131, - 48392, 48655, 48919, 49185, 49452, 49720, 49990, 50262, - 50535, 50809, 51085, 51362, 51641, 51922, 52204, 52487, - 52772, 53059, 53347, 53636, 53928, 54220, 54515, 54811, - 55108, 55408, 55709, 56011, 56315, 56621, 56928, 57238, - 57548, 57861, 58175, 58491, 58809, 59128, 59449, 59772, - 60096, 60423, 60751, 61081, 61412, 61746, 62081, 62418, - 62757, 63098, 63440, 63785, 64131, 64479, 64830, 65182, - 65536 - }; - - private static final int[] log_2_table = { - 0, 367, 732, 1095, 1454, 1811, 2165, 2517, - 2865, 3212, 3556, 3897, 4236, 4572, 4906, 5238, - 5568, 5895, 6220, 6542, 6863, 7181, 7497, 7812, - 8124, 8434, 8742, 9048, 9352, 9654, 9954, 10252, - 10548, 10843, 11136, 11427, 11716, 12003, 12289, 12573, - 12855, 13136, 13414, 13692, 13967, 14241, 14514, 14785, - 15054, 15322, 15588, 15853, 16117, 16378, 16639, 16898, - 17156, 17412, 17667, 17920, 18172, 18423, 18673, 18921, - 19168, 19413, 19657, 19900, 20142, 20383, 20622, 20860, - 21097, 21333, 21568, 21801, 22034, 22265, 22495, 22724, - 22952, 23178, 23404, 23628, 23852, 24074, 24296, 24516, - 24736, 24954, 25171, 25388, 25603, 25817, 26031, 26243, - 26455, 26665, 26875, 27084, 27292, 27499, 27705, 27910, - 28114, 28317, 28520, 28721, 28922, 29122, 29321, 29519, - 29716, 29913, 30109, 30304, 30498, 30691, 30884, 31076, - 31267, 31457, 31646, 31835, 32023, 32210, 32397, 32582, - 32768 - }; - - /* - Calculate log-base-2 of x (non-fixed-point). - A fixed point value is returned. - */ - public static int log_2( int x ) { - int shift; - /* Scale x to range 1.0 <= x < 2.0 */ - shift = IBXM.FP_SHIFT; - while( x < IBXM.FP_ONE ) { - x <<= 1; - shift--; - } - while( x >= ( IBXM.FP_ONE << 1 ) ) { - x >>= 1; - shift++; - } - return ( IBXM.FP_ONE * shift ) + eval_table( log_2_table, x - IBXM.FP_ONE ); - } - - /* - Raise 2 to the power x (fixed point). - A fixed point value is returned. - */ - public static int raise_2( int x ) { - int y; - y = eval_table( exp_2_table, x & IBXM.FP_MASK ) << IBXM.FP_SHIFT; - return y >> IBXM.FP_SHIFT - ( x >> IBXM.FP_SHIFT ); - } - - private static int eval_table( int[] table, int x ) { - int table_idx, table_frac, c, m, y; - table_idx = x >> INTERP_SHIFT; - table_frac = x & INTERP_MASK; - c = table[ table_idx ]; - m = table[ table_idx + 1 ] - c; - y = ( m * table_frac >> INTERP_SHIFT ) + c; - return y >> 15 - IBXM.FP_SHIFT; - } -} - diff --git a/src/main/java/ibxm/Module.java b/src/main/java/ibxm/Module.java deleted file mode 100644 index ee6ed3b2c..000000000 --- a/src/main/java/ibxm/Module.java +++ /dev/null @@ -1,138 +0,0 @@ - -package ibxm; - -public class Module { - public String song_title; - public boolean linear_periods, fast_volume_slides, pal; - public int global_volume, channel_gain; - public int default_speed, default_tempo; - public int restart_sequence_index; - - private int[] initial_panning, sequence; - private Pattern[] patterns; - private Instrument[] instruments; - - private Pattern default_pattern; - private Instrument default_instrument; - - public Module() { - song_title = IBXM.VERSION; - set_num_channels( 1 ); - set_sequence_length( 1 ); - set_num_patterns( 0 ); - set_num_instruments( 0 ); - default_pattern = new Pattern(); - default_instrument = new Instrument(); - } - - public int get_num_channels() { - return initial_panning.length; - } - - public void set_num_channels( int num_channels ) { - if( num_channels < 1 ) { - num_channels = 1; - } - initial_panning = new int[ num_channels ]; - } - - public int get_initial_panning( int channel ) { - int panning; - panning = 128; - if( channel >= 0 && channel < initial_panning.length ) { - panning = initial_panning[ channel ]; - } - return panning; - } - - public void set_initial_panning( int channel, int panning ) { - if( channel >= 0 && channel < initial_panning.length ) { - initial_panning[ channel ] = panning; - } - } - - public int get_sequence_length() { - return sequence.length; - } - - public void set_sequence_length( int sequence_length ) { - if( sequence_length < 0 ) { - sequence_length = 0; - } - sequence = new int[ sequence_length ]; - } - - public void set_sequence( int sequence_index, int pattern_index ) { - if( sequence_index >= 0 && sequence_index < sequence.length ) { - sequence[ sequence_index ] = pattern_index; - } - } - - public int get_num_patterns() { - return patterns.length; - } - - public void set_num_patterns( int num_patterns ) { - if( num_patterns < 0 ) { - num_patterns = 0; - } - patterns = new Pattern[ num_patterns ]; - } - - public Pattern get_pattern_from_sequence( int sequence_index ) { - Pattern pattern; - pattern = default_pattern; - if( sequence_index >= 0 && sequence_index < sequence.length ) { - pattern = get_pattern( sequence[ sequence_index ] ); - } - return pattern; - } - - public Pattern get_pattern( int pattern_index ) { - Pattern pattern; - pattern = null; - if( pattern_index >= 0 && pattern_index < patterns.length ) { - pattern = patterns[ pattern_index ]; - } - if( pattern == null ) { - pattern = default_pattern; - } - return pattern; - } - - public void set_pattern( int pattern_index, Pattern pattern ) { - if( pattern_index >= 0 && pattern_index < patterns.length ) { - patterns[ pattern_index ] = pattern; - } - } - - public int get_num_instruments() { - return instruments.length; - } - - public void set_num_instruments( int num_instruments ) { - if( num_instruments < 0 ) { - num_instruments = 0; - } - instruments = new Instrument[ num_instruments ]; - } - - public Instrument get_instrument( int instrument_index ) { - Instrument instrument; - instrument = null; - if( instrument_index > 0 && instrument_index <= instruments.length ) { - instrument = instruments[ instrument_index - 1 ]; - } - if( instrument == null ) { - instrument = default_instrument; - } - return instrument; - } - - public void set_instrument( int instrument_index, Instrument instrument ) { - if( instrument_index > 0 && instrument_index <= instruments.length ) { - instruments[ instrument_index - 1 ] = instrument; - } - } -} - diff --git a/src/main/java/ibxm/Pattern.java b/src/main/java/ibxm/Pattern.java deleted file mode 100644 index 3a0f961e2..000000000 --- a/src/main/java/ibxm/Pattern.java +++ /dev/null @@ -1,61 +0,0 @@ - -package ibxm; - -public class Pattern { - public int num_rows; - - private int data_offset, note_index; - private byte[] pattern_data; - - public Pattern() { - num_rows = 1; - set_pattern_data( new byte[ 0 ] ); - } - - public void set_pattern_data( byte[] data ) { - if( data != null ) { - pattern_data = data; - } - data_offset = 0; - note_index = 0; - } - - public void get_note( int[] note, int index ) { - if( index < note_index ) { - note_index = 0; - data_offset = 0; - } - while( note_index <= index ) { - data_offset = next_note( data_offset, note ); - note_index += 1; - } - } - - public int next_note( int data_offset, int[] note ) { - int bitmask, field; - if( data_offset < 0 ) { - data_offset = pattern_data.length; - } - bitmask = 0x80; - if( data_offset < pattern_data.length ) { - bitmask = pattern_data[ data_offset ] & 0xFF; - } - if( ( bitmask & 0x80 ) == 0x80 ) { - data_offset += 1; - } else { - bitmask = 0x1F; - } - for( field = 0; field < 5; field++ ) { - note[ field ] = 0; - if( ( bitmask & 0x01 ) == 0x01 ) { - if( data_offset < pattern_data.length ) { - note[ field ] = pattern_data[ data_offset ] & 0xFF; - data_offset += 1; - } - } - bitmask = bitmask >> 1; - } - return data_offset; - } -} - diff --git a/src/main/java/ibxm/Player.java b/src/main/java/ibxm/Player.java deleted file mode 100644 index 1b4471cc6..000000000 --- a/src/main/java/ibxm/Player.java +++ /dev/null @@ -1,133 +0,0 @@ - -package ibxm; - -import java.io.*; -import javax.sound.sampled.*; - -public class Player { - private Thread play_thread; - private IBXM ibxm; - private Module module; - private int song_duration, play_position; - private boolean running, loop; - private byte[] output_buffer; - private SourceDataLine output_line; - - /** - Simple command-line test player. - */ - public static void main( String[] args ) throws Exception { - if( args.length < 1 ) { - System.err.println( "Usage: java ibxm.Player " ); - System.exit( 0 ); - } - FileInputStream file_input_stream = new FileInputStream( args[ 0 ] ); - Player player = new Player(); - player.set_module( Player.load_module( file_input_stream ) ); - file_input_stream.close(); - player.play(); - } - - /** - Decode the data in the specified InputStream into a Module instance. - @param input an InputStream containing the module file to be decoded. - @throws IllegalArgumentException if the data is not recognised as a module file. - */ - public static Module load_module( InputStream input ) throws IllegalArgumentException, IOException { - DataInputStream data_input_stream = new DataInputStream( input ); - /* Check if data is in XM format.*/ - byte[] xm_header = new byte[ 60 ]; - data_input_stream.readFully( xm_header ); - if( FastTracker2.is_xm( xm_header ) ) - return FastTracker2.load_xm( xm_header, data_input_stream ); - /* Check if data is in ScreamTracker 3 format.*/ - byte[] s3m_header = new byte[ 96 ]; - System.arraycopy( xm_header, 0, s3m_header, 0, 60 ); - data_input_stream.readFully( s3m_header, 60, 36 ); - if( ScreamTracker3.is_s3m( s3m_header ) ) - return ScreamTracker3.load_s3m( s3m_header, data_input_stream ); - /* Check if data is in ProTracker format.*/ - byte[] mod_header = new byte[ 1084 ]; - System.arraycopy( s3m_header, 0, mod_header, 0, 96 ); - data_input_stream.readFully( mod_header, 96, 988 ); - return ProTracker.load_mod( mod_header, data_input_stream ); - } - - /** - Instantiate a new Player. - */ - public Player() throws LineUnavailableException { - ibxm = new IBXM( 48000 ); - set_loop( true ); - output_line = AudioSystem.getSourceDataLine( new AudioFormat( 48000, 16, 2, true, true ) ); - output_buffer = new byte[ 1024 * 4 ]; - } - - /** - Set the Module instance to be played. - */ - public void set_module( Module m ) { - if( m != null ) module = m; - stop(); - ibxm.set_module( module ); - song_duration = ibxm.calculate_song_duration(); - } - - /** - If loop is true, playback will continue indefinitely, - otherwise the module will play through once and stop. - */ - public void set_loop( boolean loop ) { - this.loop = loop; - } - - /** - Open the audio device and begin playback. - If a module is already playing it will be restarted. - */ - public void play() { - stop(); - play_thread = new Thread( new Driver() ); - play_thread.start(); - } - - /** - Stop playback and close the audio device. - */ - public void stop() { - running = false; - if( play_thread != null ) { - try { - play_thread.join(); - } catch( InterruptedException ie ) {} - } - } - - private class Driver implements Runnable { - @Override - public void run() { - if( running ) return; - try { - output_line.open(); - output_line.start(); - play_position = 0; - running = true; - while( running ) { - int frames = song_duration - play_position; - if( frames > 1024 ) frames = 1024; - ibxm.get_audio( output_buffer, frames ); - output_line.write( output_buffer, 0, frames * 4 ); - play_position += frames; - if( play_position >= song_duration ) { - play_position = 0; - if( !loop ) running = false; - } - } - output_line.drain(); - output_line.close(); - } catch( LineUnavailableException lue ) { - lue.printStackTrace(); - } - } - } -} diff --git a/src/main/java/ibxm/ProTracker.java b/src/main/java/ibxm/ProTracker.java deleted file mode 100644 index 4302601a2..000000000 --- a/src/main/java/ibxm/ProTracker.java +++ /dev/null @@ -1,234 +0,0 @@ -package ibxm; - -import java.io.*; - -public class ProTracker { - public static boolean is_mod( byte[] header_1084_bytes ) { - boolean is_mod; - is_mod = false; - if( calculate_num_channels( header_1084_bytes ) > 0 ) { - is_mod = true; - } - return is_mod; - } - - public static Module load_mod( byte[] header_1084_bytes, DataInput data_input ) throws IOException { - int num_channels, channel_idx, panning; - int sequence_length, restart_idx, sequence_idx; - int num_patterns, pattern_idx, instrument_idx; - Module module; - num_channels = calculate_num_channels( header_1084_bytes ); - if( num_channels < 1 ) { - throw new IllegalArgumentException( "ProTracker: Unrecognised module format!" ); - } - module = new Module(); - module.song_title = ascii_text( header_1084_bytes, 0, 20 ); - module.pal = ( num_channels == 4 ); - module.global_volume = 64; - module.channel_gain = IBXM.FP_ONE * 3 / 8; - module.default_speed = 6; - module.default_tempo = 125; - module.set_num_channels( num_channels ); - for( channel_idx = 0; channel_idx < num_channels; channel_idx++ ) { - panning = 64; - if( ( channel_idx & 0x03 ) == 0x01 || ( channel_idx & 0x03 ) == 0x02 ) { - panning = 192; - } - module.set_initial_panning( channel_idx, panning ); - } - sequence_length = header_1084_bytes[ 950 ] & 0x7F; - restart_idx = header_1084_bytes[ 951 ] & 0x7F; - if( restart_idx >= sequence_length ) { - restart_idx = 0; - } - module.restart_sequence_index = restart_idx; - module.set_sequence_length( sequence_length ); - for( sequence_idx = 0; sequence_idx < sequence_length; sequence_idx++ ) { - module.set_sequence( sequence_idx, header_1084_bytes[ 952 + sequence_idx ] & 0x7F ); - } - num_patterns = calculate_num_patterns( header_1084_bytes ); - module.set_num_patterns( num_patterns ); - for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { - module.set_pattern( pattern_idx, read_mod_pattern( data_input, num_channels ) ); - } - module.set_num_instruments( 31 ); - for( instrument_idx = 1; instrument_idx <= 31; instrument_idx++ ) { - module.set_instrument( instrument_idx, read_mod_instrument( header_1084_bytes, instrument_idx, data_input ) ); - } - return module; - } - - private static int calculate_num_patterns( byte[] module_header ) { - int num_patterns, order_entry, pattern_idx; - num_patterns = 0; - for( pattern_idx = 0; pattern_idx < 128; pattern_idx++ ) { - order_entry = module_header[ 952 + pattern_idx ] & 0x7F; - if( order_entry >= num_patterns ) { - num_patterns = order_entry + 1; - } - } - return num_patterns; - } - - private static int calculate_num_channels( byte[] module_header ) { - int num_channels; - switch( ( module_header[ 1082 ] << 8 ) | module_header[ 1083 ] ) { - case 0x4b2e: /* M.K. */ - case 0x4b21: /* M!K! */ - case 0x542e: /* N.T. */ - case 0x5434: /* FLT4 */ - num_channels = 4; - break; - case 0x484e: /* xCHN */ - num_channels = module_header[ 1080 ] - 48; - break; - case 0x4348: /* xxCH */ - num_channels = ( ( module_header[ 1080 ] - 48 ) * 10 ) + ( module_header[ 1081 ] - 48 ); - break; - default: - /* Not recognised. */ - num_channels = 0; - break; - } - return num_channels; - } - - private static Pattern read_mod_pattern( DataInput data_input, int num_channels ) throws IOException { - int input_idx, output_idx; - int period, instrument, effect, effect_param; - Pattern pattern; - byte[] input_pattern_data, output_pattern_data; - pattern = new Pattern(); - pattern.num_rows = 64; - input_pattern_data = new byte[ 64 * num_channels * 4 ]; - output_pattern_data = new byte[ 64 * num_channels * 5 ]; - data_input.readFully( input_pattern_data ); - input_idx = 0; - output_idx = 0; - while( input_idx < input_pattern_data.length ) { - period = ( input_pattern_data[ input_idx ] & 0x0F ) << 8; - period = period | ( input_pattern_data[ input_idx + 1 ] & 0xFF ); - output_pattern_data[ output_idx ] = to_key( period ); - instrument = input_pattern_data[ input_idx ] & 0x10; - instrument = instrument | ( ( input_pattern_data[ input_idx + 2 ] & 0xF0 ) >> 4 ); - output_pattern_data[ output_idx + 1 ] = ( byte ) instrument; - effect = input_pattern_data[ input_idx + 2 ] & 0x0F; - effect_param = input_pattern_data[ input_idx + 3 ] & 0xFF; - if( effect == 0x01 && effect_param == 0 ) { - /* Portamento up of zero has no effect. */ - effect = 0; - } - if( effect == 0x02 && effect_param == 0 ) { - /* Portamento down of zero has no effect. */ - effect = 0; - } - if( effect == 0x08 && num_channels == 4 ) { - /* Some Amiga mods use effect 0x08 for reasons other than panning.*/ - effect = 0; - effect_param = 0; - } - if( effect == 0x0A && effect_param == 0 ) { - /* Volume slide of zero has no effect.*/ - effect = 0; - } - if( effect == 0x05 && effect_param == 0 ) { - /* Porta + Volume slide of zero has no effect.*/ - effect = 0x03; - } - if( effect == 0x06 && effect_param == 0 ) { - /* Vibrato + Volume slide of zero has no effect.*/ - effect = 0x04; - } - output_pattern_data[ output_idx + 3 ] = ( byte ) effect; - output_pattern_data[ output_idx + 4 ] = ( byte ) effect_param; - input_idx += 4; - output_idx += 5; - } - pattern.set_pattern_data( output_pattern_data ); - return pattern; - } - - private static Instrument read_mod_instrument( byte[] mod_header, int idx, DataInput data_input ) throws IOException { - int header_offset, sample_data_length; - int loop_start, loop_length, sample_idx, fine_tune; - Instrument instrument; - Sample sample; - byte[] raw_sample_data; - short[] sample_data; - header_offset = ( idx - 1 ) * 30 + 20; - instrument = new Instrument(); - instrument.name = ascii_text( mod_header, header_offset, 22 ); - sample = new Sample(); - sample_data_length = unsigned_short_be( mod_header, header_offset + 22 ) << 1; - fine_tune = mod_header[ header_offset + 24 ] & 0x0F; - if( fine_tune > 7 ) { - fine_tune -= 16; - } - sample.transpose = ( fine_tune << IBXM.FP_SHIFT ) / 96; - sample.volume = mod_header[ header_offset + 25 ] & 0x7F; - loop_start = unsigned_short_be( mod_header, header_offset + 26 ) << 1; - loop_length = unsigned_short_be( mod_header, header_offset + 28 ) << 1; - if( loop_length < 4 ) { - loop_length = 0; - } - raw_sample_data = new byte[ sample_data_length ]; - sample_data = new short[ sample_data_length ]; - try { - data_input.readFully( raw_sample_data ); - } catch( EOFException e ) { - System.out.println( "ProTracker: Instrument " + idx + " has samples missing." ); - } - for( sample_idx = 0; sample_idx < raw_sample_data.length; sample_idx++ ) { - sample_data[ sample_idx ] = ( short ) ( raw_sample_data[ sample_idx ] << 8 ); - } - sample.set_sample_data( sample_data, loop_start, loop_length, false ); - instrument.set_num_samples( 1 ); - instrument.set_sample( 0, sample ); - return instrument; - } - - private static byte to_key( int period ) { - int oct, key; - if( period < 32 ) { - key = 0; - } else { - oct = LogTable.log_2( 7256 ) - LogTable.log_2( period ); - if( oct < 0 ) { - key = 0; - } else { - key = oct * 12; - key = key >> ( IBXM.FP_SHIFT - 1 ); - key = ( key >> 1 ) + ( key & 1 ); - } - } - return ( byte ) key; - } - - private static int unsigned_short_be( byte[] buf, int offset ) { - int value; - value = ( buf[ offset ] & 0xFF ) << 8; - value = value | ( buf[ offset + 1 ] & 0xFF ); - return value; - } - - private static String ascii_text( byte[] buffer, int offset, int length ) { - int idx, chr; - byte[] string_buffer; - String string; - string_buffer = new byte[ length ]; - for( idx = 0; idx < length; idx++ ) { - chr = buffer[ offset + idx ]; - if( chr < 32 ) { - chr = 32; - } - string_buffer[ idx ] = ( byte ) chr; - } - try { - string = new String( string_buffer, 0, length, "ISO-8859-1" ); - } catch( UnsupportedEncodingException e ) { - string = ""; - } - return string; - } -} - diff --git a/src/main/java/ibxm/Sample.java b/src/main/java/ibxm/Sample.java deleted file mode 100644 index 2fb30f5c2..000000000 --- a/src/main/java/ibxm/Sample.java +++ /dev/null @@ -1,239 +0,0 @@ - -package ibxm; - -public class Sample { - public String name; - public boolean set_panning; - public int volume, panning; - public int transpose; - - private int loop_start, loop_length; - private short[] sample_data; - - /* For the sinc interpolator.*/ - private static final int POINT_SHIFT = 4; - private static final int POINTS = 1 << POINT_SHIFT; - private static final int OVERLAP = POINTS >> 1; - private static final int INTERP_SHIFT = IBXM.FP_SHIFT - 4; - private static final int INTERP_BITMASK = ( 1 << INTERP_SHIFT ) - 1; - private static final short[] sinc_table = { - 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, 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, - -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, -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, - 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, 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, 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, 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, 0, -7, 27, -71, 142, -227, 299, 32439, 299, -227, 142, -71, 27, -7, 0 - }; - - public Sample() { - name = ""; - 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 ) { - int offset; - short sample; - if( loop_start < 0 ) { - loop_start = 0; - } - if( loop_start >= data.length ) { - loop_start = data.length - 1; - } - if( loop_start + loop_length > data.length ) { - loop_length = data.length - loop_start; - } - if( loop_length <= 1 ) { - sample_data = new short[ OVERLAP + data.length + OVERLAP * 3 ]; - System.arraycopy( data, 0, sample_data, OVERLAP, data.length ); - offset = 0; - while( offset < OVERLAP ) { - sample = sample_data[ OVERLAP + data.length - 1 ]; - sample = ( short ) ( sample * ( OVERLAP - offset ) / OVERLAP ); - sample_data[ OVERLAP + data.length + offset ] = sample; - offset += 1; - } - loop_start = OVERLAP + data.length + OVERLAP; - loop_length = 1; - } else { - if( ping_pong ) { - sample_data = new short[ OVERLAP + loop_start + loop_length * 2 + OVERLAP * 2 ]; - System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length ); - offset = 0; - while( offset < loop_length ) { - sample = data[ loop_start + loop_length - offset - 1 ]; - sample_data[ OVERLAP + loop_start + loop_length + offset ] = sample; - offset += 1; - } - loop_start = loop_start + OVERLAP; - loop_length = loop_length * 2; - } else { - sample_data = new short[ OVERLAP + loop_start + loop_length + OVERLAP * 2 ]; - System.arraycopy( data, 0, sample_data, OVERLAP, loop_start + loop_length ); - loop_start = loop_start + OVERLAP; - } - offset = 0; - while( offset < OVERLAP * 2 ) { - sample = sample_data[ loop_start + offset ]; - sample_data[ loop_start + loop_length + offset ] = sample; - offset += 1; - } - } - this.loop_start = loop_start; - this.loop_length = loop_length; - } - - public void resample_nearest( - int sample_idx, int sample_frac, int step, int left_gain, int right_gain, - int[] mix_buffer, int frame_offset, int frames ) { - int loop_end, offset, end, max_sample_idx; - sample_idx += OVERLAP; - loop_end = loop_start + loop_length - 1; - offset = frame_offset << 1; - end = ( frame_offset + frames - 1 ) << 1; - while( frames > 0 ) { - if( sample_idx > loop_end ) { - if( loop_length <= 1 ) { - break; - } - sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length; - } - max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT ); - if( max_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 ] * right_gain >> IBXM.FP_SHIFT; - sample_frac += step; - sample_idx += sample_frac >> IBXM.FP_SHIFT; - sample_frac &= IBXM.FP_MASK; - } - } else { - while( offset <= end ) { - mix_buffer[ offset++ ] += sample_data[ sample_idx ] * left_gain >> IBXM.FP_SHIFT; - mix_buffer[ offset++ ] += sample_data[ sample_idx ] * right_gain >> IBXM.FP_SHIFT; - sample_frac += step; - sample_idx += sample_frac >> IBXM.FP_SHIFT; - sample_frac &= IBXM.FP_MASK; - } - } - frames = ( end - offset + 2 ) >> 1; - } - } - - public void resample_linear( - int sample_idx, int sample_frac, int step, int left_gain, int right_gain, - int[] mix_buffer, int frame_offset, int frames ) { - int loop_end, offset, end, max_sample_idx, amplitude; - sample_idx += OVERLAP; - loop_end = loop_start + loop_length - 1; - offset = frame_offset << 1; - end = ( frame_offset + frames - 1 ) << 1; - while( frames > 0 ) { - if( sample_idx > loop_end ) { - if( loop_length <= 1 ) { - break; - } - sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length; - } - max_sample_idx = sample_idx + ( ( sample_frac + ( frames - 1 ) * step ) >> IBXM.FP_SHIFT ); - if( max_sample_idx > loop_end ) { - while( sample_idx <= loop_end ) { - amplitude = sample_data[ sample_idx ]; - 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 * right_gain >> IBXM.FP_SHIFT; - sample_frac += step; - sample_idx += sample_frac >> IBXM.FP_SHIFT; - sample_frac &= IBXM.FP_MASK; - } - } else { - while( offset <= end ) { - amplitude = sample_data[ sample_idx ]; - 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 * right_gain >> IBXM.FP_SHIFT; - sample_frac += step; - sample_idx += sample_frac >> IBXM.FP_SHIFT; - sample_frac &= IBXM.FP_MASK; - } - } - frames = ( end - offset + 2 ) >> 1; - } - } - - public void resample_sinc( - int sample_idx, int sample_frac, int step, int left_gain, int right_gain, - int[] mix_buffer, int frame_offset, int frames ) { - int offset, end, loop_end, table_idx, a1, a2, amplitude; - loop_end = loop_start + loop_length - 1; - offset = frame_offset << 1; - end = ( frame_offset + frames - 1 ) << 1; - while( offset <= end ) { - if( sample_idx > loop_end ) { - if( loop_length <= 1 ) { - break; - } - sample_idx = loop_start + ( sample_idx - loop_start ) % loop_length; - } - 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 + 1 ] * sample_data[ sample_idx + 1 ] >> 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 + 4 ] * sample_data[ sample_idx + 4 ] >> 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 + 7 ] * sample_data[ sample_idx + 7 ] >> 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 + 10 ] * sample_data[ sample_idx + 10 ] >> 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 + 13 ] * sample_data[ sample_idx + 13 ] >> 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; - 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 + 18 ] * sample_data[ sample_idx + 2 ] >> 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 + 21 ] * sample_data[ sample_idx + 5 ] >> 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 + 24 ] * sample_data[ sample_idx + 8 ] >> 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 + 27 ] * sample_data[ sample_idx + 11 ] >> 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 + 30 ] * sample_data[ sample_idx + 14 ] >> 15; - a2 += sinc_table[ table_idx + 31 ] * sample_data[ sample_idx + 15 ] >> 15; - amplitude = a1 + ( ( a2 - a1 ) * ( sample_frac & INTERP_BITMASK ) >> INTERP_SHIFT ); - mix_buffer[ offset ] += amplitude * left_gain >> IBXM.FP_SHIFT; - mix_buffer[ offset + 1 ] += amplitude * right_gain >> IBXM.FP_SHIFT; - offset += 2; - sample_frac += step; - sample_idx += sample_frac >> IBXM.FP_SHIFT; - sample_frac &= IBXM.FP_MASK; - } - } - - public boolean has_finished( int sample_idx ) { - boolean finished; - finished = false; - if( loop_length <= 1 && sample_idx > loop_start ) { - finished = true; - } - return finished; - } -} diff --git a/src/main/java/ibxm/ScreamTracker3.java b/src/main/java/ibxm/ScreamTracker3.java deleted file mode 100644 index 26144703e..000000000 --- a/src/main/java/ibxm/ScreamTracker3.java +++ /dev/null @@ -1,490 +0,0 @@ - -package ibxm; - -import java.io.*; - -public class ScreamTracker3 { - private static final int[] effect_map = new int[] { - 0xFF, - 0x25, /* A: Set Speed.*/ - 0x0B, /* B: Pattern Jump.*/ - 0x0D, /* C: Pattern Break.*/ - 0x0A, /* D: Volume Slide.*/ - 0x02, /* E: Portamento Down.*/ - 0x01, /* F: Portamento Up.*/ - 0x03, /* G: Tone Portamento.*/ - 0x04, /* H: Vibrato.*/ - 0x1D, /* I: Tremor.*/ - 0x00, /* J: Arpeggio.*/ - 0x06, /* K: Vibrato + Volume Slide.*/ - 0x05, /* L: Tone Portamento + Volume Slide.*/ - 0xFF, /* M: */ - 0xFF, /* N: */ - 0x09, /* O: Sample Offset.*/ - 0xFF, /* P: */ - 0x1B, /* Q: Retrig + Volume Slide.*/ - 0x07, /* R: Tremolo.*/ - 0x0E, /* S: Extended Effects.*/ - 0x0F, /* T: Set Tempo.*/ - 0x24, /* U: Fine Vibrato.*/ - 0x10, /* V: Set Global Volume. */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF - }; - - private static final int[] effect_s_map = new int[] { - 0x00, /* 0: Set Filter.*/ - 0x03, /* 1: Glissando.*/ - 0x05, /* 2: Set Fine Tune.*/ - 0x04, /* 3: Set Vibrato Waveform.*/ - 0x07, /* 4: Set Tremolo Waveform.*/ - 0xFF, /* 5: */ - 0xFF, /* 6: */ - 0xFF, /* 7: */ - 0x08, /* 8: Set Panning.*/ - 0xFF, /* 9: */ - 0x09, /* A: Stereo Control.*/ - 0x06, /* B: Pattern Loop.*/ - 0x0C, /* C: Note Cut.*/ - 0x0D, /* D: Note Delay.*/ - 0x0E, /* E: Pattern Delay.*/ - 0x0F /* F: Invert Loop.*/ - }; - - public static boolean is_s3m( byte[] header_96_bytes ) { - String s3m_identifier; - s3m_identifier = ascii_text( header_96_bytes, 44, 4 ); - return s3m_identifier.equals( "SCRM" ); - } - - public static Module load_s3m( byte[] header_96_bytes, DataInput data_input ) throws IOException { - int num_pattern_orders, num_instruments, num_patterns, num_channels; - @SuppressWarnings("unused") //Forge - int flags, tracker_version, master_volume, panning, channel_config, sequence_length; - int instrument_idx, pattern_idx, channel_idx, order_idx, panning_offset; - boolean signed_samples, stereo_mode, default_panning; - int[] channel_map, sequence; - byte[] s3m_file; - Module module; - Instrument instrument; - s3m_file = read_s3m_file( header_96_bytes, data_input ); - module = new Module(); - module.song_title = ascii_text( s3m_file, 0, 28 ); - num_pattern_orders = get_num_pattern_orders( s3m_file ); - num_instruments = get_num_instruments( s3m_file ); - num_patterns = get_num_patterns( s3m_file ); - flags = unsigned_short_le( s3m_file, 38 ); - tracker_version = unsigned_short_le( s3m_file, 40 ); - if( ( flags & 0x40 ) == 0x40 || tracker_version == 0x1300 ) { - module.fast_volume_slides = true; - } - signed_samples = false; - if( unsigned_short_le( s3m_file, 42 ) == 0x01 ) { - signed_samples = true; - } - module.global_volume = s3m_file[ 48 ] & 0xFF; - module.default_speed = s3m_file[ 49 ] & 0xFF; - module.default_tempo = s3m_file[ 50 ] & 0xFF; - master_volume = s3m_file[ 51 ] & 0x7F; - module.channel_gain = ( master_volume << IBXM.FP_SHIFT ) >> 7; - stereo_mode = ( s3m_file[ 51 ] & 0x80 ) == 0x80; - default_panning = ( s3m_file[ 53 ] & 0xFF ) == 0xFC; - channel_map = new int[ 32 ]; - num_channels = 0; - for( channel_idx = 0; channel_idx < 32; channel_idx++ ) { - channel_config = s3m_file[ 64 + channel_idx ] & 0xFF; - channel_map[ channel_idx ] = -1; - if( channel_config < 16 ) { - channel_map[ channel_idx ] = num_channels; - num_channels += 1; - } - } - module.set_num_channels( num_channels ); - panning_offset = 96 + num_pattern_orders + num_instruments * 2 + num_patterns * 2; - for( channel_idx = 0; channel_idx < 32; channel_idx++ ) { - if( channel_map[ channel_idx ] < 0 ) continue; - panning = 7; - if( stereo_mode ) { - panning = 12; - if( ( s3m_file[ 64 + channel_idx ] & 0xFF ) < 8 ) { - panning = 3; - } - } - if( default_panning ) { - flags = s3m_file[ panning_offset + channel_idx ] & 0xFF; - if( ( flags & 0x20 ) == 0x20 ) { - panning = flags & 0xF; - } - } - module.set_initial_panning( channel_map[ channel_idx ], panning * 17 ); - } - sequence = read_s3m_sequence( s3m_file ); - module.set_sequence_length( sequence.length ); - for( order_idx = 0; order_idx < sequence.length; order_idx++ ) { - module.set_sequence( order_idx, sequence[ order_idx ] ); - } - module.set_num_instruments( num_instruments ); - for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) { - instrument = read_s3m_instrument( s3m_file, instrument_idx, signed_samples ); - module.set_instrument( instrument_idx + 1, instrument ); - } - module.set_num_patterns( num_patterns ); - for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { - module.set_pattern( pattern_idx, read_s3m_pattern( s3m_file, pattern_idx, channel_map ) ); - } - return module; - } - - private static int[] read_s3m_sequence( byte[] s3m_file ) { - int num_pattern_orders, sequence_length; - int sequence_idx, order_idx, pattern_order; - int[] sequence; - num_pattern_orders = get_num_pattern_orders( s3m_file ); - sequence_length = 0; - for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) { - pattern_order = s3m_file[ 96 + order_idx ] & 0xFF; - if( pattern_order == 255 ) { - break; - } else if( pattern_order < 254 ) { - sequence_length += 1; - } - } - sequence = new int[ sequence_length ]; - sequence_idx = 0; - for( order_idx = 0; order_idx < num_pattern_orders; order_idx++ ) { - pattern_order = s3m_file[ 96 + order_idx ] & 0xFF; - if( pattern_order == 255 ) { - break; - } else if( pattern_order < 254 ) { - sequence[ sequence_idx ] = pattern_order; - sequence_idx += 1; - } - } - return sequence; - } - - private static Instrument read_s3m_instrument( byte[] s3m_file, int instrument_idx, boolean signed_samples ) { - int instrument_offset; - int sample_data_offset, sample_data_length; - int loop_start, loop_length, c2_rate, sample_idx, amplitude; - boolean sixteen_bit; - Instrument instrument; - Sample sample; - short[] sample_data; - instrument_offset = get_instrument_offset( s3m_file, instrument_idx ); - instrument = new Instrument(); - instrument.name = ascii_text( s3m_file, instrument_offset + 48, 28 ); - sample = new Sample(); - if( s3m_file[ instrument_offset ] == 1 ) { - sample_data_length = get_sample_data_length( s3m_file, instrument_offset ); - loop_start = unsigned_short_le( s3m_file, instrument_offset + 20 ); - loop_length = unsigned_short_le( s3m_file, instrument_offset + 24 ) - loop_start; - sample.volume = s3m_file[ instrument_offset + 28 ] & 0xFF; - if( s3m_file[ instrument_offset + 30 ] != 0 ) { - throw new IllegalArgumentException( "ScreamTracker3: Packed samples not supported!" ); - } - if( ( s3m_file[ instrument_offset + 31 ] & 0x01 ) == 0 ) { - loop_length = 0; - } - if( ( s3m_file[ instrument_offset + 31 ] & 0x02 ) != 0 ) { - throw new IllegalArgumentException( "ScreamTracker3: Stereo samples not supported!" ); - } - sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0; - c2_rate = unsigned_short_le( s3m_file, instrument_offset + 32 ); - sample.transpose = LogTable.log_2( c2_rate ) - LogTable.log_2( 8363 ); - sample_data_offset = get_sample_data_offset( s3m_file, instrument_offset ); - if( sixteen_bit ) { - if( signed_samples ) { - throw new IllegalArgumentException( "ScreamTracker3: Signed 16-bit samples not supported!" ); - } - sample_data_length >>= 1; - sample_data = new short[ sample_data_length ]; - 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 + 1 ] & 0xFF ) << 8; - sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 ); - } - } else { - sample_data = new short[ sample_data_length ]; - if( signed_samples ) { - for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) { - amplitude = s3m_file[ sample_data_offset + sample_idx ] << 8; - sample_data[ sample_idx ] = ( short ) amplitude; - } - } else { - for( sample_idx = 0; sample_idx < sample_data_length; sample_idx++ ) { - amplitude = ( s3m_file[ sample_data_offset + sample_idx ] & 0xFF ) << 8; - sample_data[ sample_idx ] = ( short ) ( amplitude - 32768 ); - } - } - } - sample.set_sample_data( sample_data, loop_start, loop_length, false ); - } - instrument.set_num_samples( 1 ); - instrument.set_sample( 0, sample ); - return instrument; - } - - private static Pattern read_s3m_pattern( byte[] s3m_file, int pattern_idx, int[] channel_map ) { - int pattern_offset; - int num_channels, num_notes; - int row_idx, channel_idx, note_idx; - int token, key, volume_column, effect, effect_param; - byte[] pattern_data; - Pattern pattern; - num_channels = 0; - for( channel_idx = 0; channel_idx < 32; channel_idx++ ) { - if( channel_map[ channel_idx ] >= num_channels ) { - num_channels = channel_idx + 1; - } - } - num_notes = num_channels * 64; - pattern_data = new byte[ num_notes * 5 ]; - row_idx = 0; - pattern_offset = get_pattern_offset( s3m_file, pattern_idx ) + 2; - while( row_idx < 64 ) { - token = s3m_file[ pattern_offset ] & 0xFF; - pattern_offset += 1; - if( token > 0 ) { - channel_idx = channel_map[ token & 0x1F ]; - note_idx = ( num_channels * row_idx + channel_idx ) * 5; - if( ( token & 0x20 ) == 0x20 ) { - /* Key + Instrument.*/ - if( channel_idx >= 0 ) { - key = s3m_file[ pattern_offset ] & 0xFF; - if( key == 255 ) { - key = 0; - } else if( key == 254 ) { - key = 97; - } else { - key = ( ( key & 0xF0 ) >> 4 ) * 12 + ( key & 0x0F ) + 1; - while( key > 96 ) { - key = key - 12; - } - } - pattern_data[ note_idx ] = ( byte ) key; - pattern_data[ note_idx + 1 ] = s3m_file[ pattern_offset + 1 ]; - } - pattern_offset += 2; - } - if( ( token & 0x40 ) == 0x40 ) { - /* Volume.*/ - if( channel_idx >= 0 ) { - volume_column = ( s3m_file[ pattern_offset ] & 0xFF ) + 0x10; - pattern_data[ note_idx + 2 ] = ( byte ) volume_column; - } - pattern_offset += 1; - } - if( ( token & 0x80 ) == 0x80 ) { - /* Effect + Param.*/ - if( channel_idx >= 0 ) { - effect = s3m_file[ pattern_offset ] & 0xFF; - effect_param = s3m_file[ pattern_offset + 1 ] & 0xFF; - effect = effect_map[ effect & 0x1F ]; - if( effect == 0xFF ) { - effect = 0; - effect_param = 0; - } - if( effect == 0x0E ) { - effect = effect_s_map[ ( effect_param & 0xF0 ) >> 4 ]; - effect_param = effect_param & 0x0F; - switch( effect ) { - case 0x08: - effect = 0x08; - effect_param = effect_param * 17; - break; - case 0x09: - effect = 0x08; - if( effect_param > 7 ) { - effect_param -= 8; - } else { - effect_param += 8; - } - effect_param = effect_param * 17; - break; - case 0xFF: - effect = 0; - effect_param = 0; - break; - default: - effect_param = ( ( effect & 0x0F ) << 4 ) | ( effect_param & 0x0F ); - effect = 0x0E; - break; - } - } - pattern_data[ note_idx + 3 ] = ( byte ) effect; - pattern_data[ note_idx + 4 ] = ( byte ) effect_param; - } - pattern_offset += 2; - } - } else { - row_idx += 1; - } - } - pattern = new Pattern(); - pattern.num_rows = 64; - pattern.set_pattern_data( pattern_data ); - return pattern; - } - - private static byte[] read_s3m_file( byte[] header_96_bytes, DataInput data_input ) throws IOException { - int s3m_file_length; - int num_pattern_orders, num_instruments, num_patterns; - int instrument_idx, pattern_idx; - int instrument_offset, sample_data_offset, pattern_offset; - byte[] s3m_file; - if( !is_s3m( header_96_bytes ) ) { - throw new IllegalArgumentException( "ScreamTracker3: Not an S3M file!" ); - } - s3m_file = header_96_bytes; - s3m_file_length = header_96_bytes.length; - num_pattern_orders = get_num_pattern_orders( s3m_file ); - num_instruments = get_num_instruments( s3m_file ); - num_patterns = get_num_patterns( s3m_file ); - s3m_file_length += num_pattern_orders; - s3m_file_length += num_instruments * 2; - s3m_file_length += num_patterns * 2; - /* Read enough of file to calculate the length.*/ - s3m_file = read_more( s3m_file, s3m_file_length, data_input ); - for( instrument_idx = 0; instrument_idx < num_instruments; instrument_idx++ ) { - instrument_offset = get_instrument_offset( s3m_file, instrument_idx ); - instrument_offset += 80; - if( instrument_offset > s3m_file_length ) { - s3m_file_length = instrument_offset; - } - } - for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { - pattern_offset = get_pattern_offset( s3m_file, pattern_idx ); - pattern_offset += 2; - if( pattern_offset > s3m_file_length ) { - s3m_file_length = pattern_offset; - } - } - s3m_file = read_more( s3m_file, s3m_file_length, data_input ); - /* Read rest of file.*/ - for( instrument_idx = 0; instrument_idx < num_instruments; 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_length( s3m_file, instrument_offset ); - if( sample_data_offset > s3m_file_length ) { - s3m_file_length = sample_data_offset; - } - } - for( pattern_idx = 0; pattern_idx < num_patterns; pattern_idx++ ) { - pattern_offset = get_pattern_offset( s3m_file, pattern_idx ); - pattern_offset += get_pattern_length( s3m_file, pattern_offset ); - pattern_offset += 2; - if( pattern_offset > s3m_file_length ) { - s3m_file_length = pattern_offset; - } - } - s3m_file = read_more( s3m_file, s3m_file_length, data_input ); - return s3m_file; - } - - private static int get_num_pattern_orders( byte[] s3m_file ) { - int num_pattern_orders; - num_pattern_orders = unsigned_short_le( s3m_file, 32 ); - return num_pattern_orders; - } - - private static int get_num_instruments( byte[] s3m_file ) { - int num_instruments; - num_instruments = unsigned_short_le( s3m_file, 34 ); - return num_instruments; - } - - private static int get_num_patterns( byte[] s3m_file ) { - int num_patterns; - num_patterns = unsigned_short_le( s3m_file, 36 ); - return num_patterns; - } - - private static int get_instrument_offset( byte[] s3m_file, int instrument_idx ) { - int instrument_offset, pointer_offset; - pointer_offset = 96 + get_num_pattern_orders( s3m_file ); - instrument_offset = unsigned_short_le( s3m_file, pointer_offset + instrument_idx * 2 ) << 4; - return instrument_offset; - } - - private static int get_sample_data_offset( byte[] s3m_file, int instrument_offset ) { - int sample_data_offset; - sample_data_offset = 0; - if( s3m_file[ instrument_offset ] == 1 ) { - sample_data_offset = ( s3m_file[ instrument_offset + 13 ] & 0xFF ) << 20; - sample_data_offset |= unsigned_short_le( s3m_file, instrument_offset + 14 ) << 4; - } - return sample_data_offset; - } - - private static int get_sample_data_length( byte[] s3m_file, int instrument_offset ) { - int sample_data_length; - boolean sixteen_bit; - sample_data_length = 0; - if( s3m_file[ instrument_offset ] == 1 ) { - sample_data_length = unsigned_short_le( s3m_file, instrument_offset + 16 ); - sixteen_bit = ( s3m_file[ instrument_offset + 31 ] & 0x04 ) != 0; - if( sixteen_bit ) { - sample_data_length <<= 1; - } - } - return sample_data_length; - } - - private static int get_pattern_offset( byte[] s3m_file, int pattern_idx ) { - int pattern_offset, pointer_offset; - pointer_offset = 96 + get_num_pattern_orders( s3m_file ); - pointer_offset += get_num_instruments( s3m_file ) * 2; - pattern_offset = unsigned_short_le( s3m_file, pointer_offset + pattern_idx * 2 ) << 4; - return pattern_offset; - } - - private static int get_pattern_length( byte[] s3m_file, int pattern_offset ) { - int pattern_length; - pattern_length = unsigned_short_le( s3m_file, pattern_offset ); - return pattern_length; - } - - private static byte[] read_more( byte[] old_data, int new_length, DataInput data_input ) throws IOException { - byte[] new_data; - new_data = old_data; - if( new_length > old_data.length ) { - new_data = new byte[ new_length ]; - System.arraycopy( old_data, 0, new_data, 0, old_data.length ); - try { - data_input.readFully( new_data, old_data.length, new_data.length - old_data.length ); - } catch( EOFException e ) { - System.out.println( "ScreamTracker3: Module has been truncated!" ); - } - } - return new_data; - } - - private static int unsigned_short_le( byte[] buffer, int offset ) { - int value; - value = buffer[ offset ] & 0xFF; - value = value | ( ( buffer[ offset + 1 ] & 0xFF ) << 8 ); - return value; - } - - private static String ascii_text( byte[] buffer, int offset, int length ) { - int idx, chr; - byte[] string_buffer; - String string; - string_buffer = new byte[ length ]; - for( idx = 0; idx < length; idx++ ) { - chr = buffer[ offset + idx ]; - if( chr < 32 ) { - chr = 32; - } - string_buffer[ idx ] = ( byte ) chr; - } - try { - string = new String( string_buffer, 0, length, "ISO-8859-1" ); - } catch( UnsupportedEncodingException e ) { - string = ""; - } - return string; - } -} - diff --git a/src/main/java/net/minecraftforge/client/EnumHelperClient.java b/src/main/java/net/minecraftforge/client/EnumHelperClient.java deleted file mode 100644 index 0fc6ed44f..000000000 --- a/src/main/java/net/minecraftforge/client/EnumHelperClient.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Minecraft Forge - * Copyright (c) 2016-2018. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -package net.minecraftforge.client; - -import net.minecraft.client.audio.MusicTicker; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.Util.EnumOS; -import net.minecraft.world.GameType; -import net.minecraft.client.settings.GameSettings.Options; -import net.minecraftforge.common.util.EnumHelper; - -import javax.annotation.Nullable; - -public class EnumHelperClient extends EnumHelper -{ - private static Class[][] clientTypes = - { - {GameType.class, int.class, String.class, String.class}, - {Options.class, String.class, boolean.class, boolean.class}, - {EnumOS.class}, - {MusicTicker.MusicType.class, SoundEvent.class, int.class, int.class} - }; - - @Nullable - public static GameType addGameType(String name, int id, String displayName, String shortName) - { - return addEnum(GameType.class, name, id, displayName, shortName); - } - - @Nullable - public static Options addOptions(String name, String langName, boolean isSlider, boolean isToggle) - { - return addEnum(Options.class, name, langName, isSlider, isToggle); - } - - @Nullable - public static Options addOptions(String name, String langName, boolean isSlider, boolean isToggle, float valMin, float valMax, float valStep) - { - return addEnum(Options.class, name, - new Class[]{String.class, boolean.class, boolean.class, float.class, float.class, float.class}, - langName, isSlider, isToggle, valMin, valMax, valStep); - } - - @Nullable - public static EnumOS addOS2(String name) - { - return addEnum(EnumOS.class, name); - } - - @Nullable - public static MusicTicker.MusicType addMusicType(String name, SoundEvent sound, int minDelay, int maxDelay) - { - return addEnum(MusicTicker.MusicType.class, name, sound, minDelay, maxDelay); - } - - @Nullable - private static > T addEnum(Class enumType, String enumName, Object... paramValues) - { - return addEnum(clientTypes, enumType, enumName, paramValues); - } -} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java index d89504f1a..6316d1b32 100644 --- a/src/main/java/net/minecraftforge/client/ForgeHooksClient.java +++ b/src/main/java/net/minecraftforge/client/ForgeHooksClient.java @@ -31,6 +31,7 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.util.Map; import java.util.Optional; +import java.util.function.Predicate; import javax.annotation.Nonnull; import javax.vecmath.Matrix3f; @@ -40,6 +41,7 @@ import javax.vecmath.Vector4f; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; +import net.minecraft.client.GameSettings; import net.minecraft.client.Minecraft; import net.minecraft.client.audio.ISound; import net.minecraft.client.audio.SoundHandler; @@ -48,15 +50,12 @@ import net.minecraft.client.gui.BossInfoClient; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.model.ModelBiped; import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.RenderGlobal; -import net.minecraft.client.renderer.RenderItem; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BlockFaceUV; import net.minecraft.client.renderer.block.model.IBakedModel; @@ -72,16 +71,13 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.renderer.vertex.VertexFormatElement; import net.minecraft.client.renderer.vertex.VertexFormatElement.EnumUsage; import net.minecraft.client.resources.FoliageColorReloadListener; import net.minecraft.client.resources.GrassColorReloadListener; import net.minecraft.client.resources.I18n; -import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.client.resources.LanguageManager; -import net.minecraft.client.settings.GameSettings; import net.minecraft.client.util.SearchTreeManager; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -101,7 +97,6 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.registry.IRegistry; import net.minecraft.util.text.TextFormatting; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraftforge.client.event.ColorHandlerEvent; @@ -111,7 +106,6 @@ import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.client.event.InputUpdateEvent; import net.minecraftforge.client.event.ModelBakeEvent; -import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderHandEvent; import net.minecraftforge.client.event.RenderSpecificHandEvent; @@ -132,25 +126,17 @@ import net.minecraftforge.common.model.IModelPart; import net.minecraftforge.common.model.ITransformation; import net.minecraftforge.common.model.TRSRTransformation; import net.minecraftforge.fml.VersionChecker; -import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.registry.ClientRegistry; -import net.minecraftforge.fml.common.FMLLog; import org.apache.commons.lang3.tuple.Pair; import org.lwjgl.BufferUtils; -import java.util.Optional; import com.google.common.collect.Maps; public class ForgeHooksClient { //private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); - static TextureManager engine() - { - return FMLClientHandler.instance().getClient().renderEngine; - } - public static String getArmorTexture(Entity entity, ItemStack armor, String _default, EntityEquipmentSlot slot, String type) { String result = armor.getItem().getArmorTexture(armor, entity, slot, type); @@ -406,18 +392,18 @@ public class ForgeHooksClient m.setIdentity(); m.setTranslation(TRSRTransformation.toVecmath(transform.translation)); t.setIdentity(); - t.rotY(transform.rotation.y); + t.rotY(transform.rotation.func_195900_b()); m.mul(t); t.setIdentity(); - t.rotX(transform.rotation.x); + t.rotX(transform.rotation.func_195899_a()); m.mul(t); t.setIdentity(); - t.rotZ(transform.rotation.z); + t.rotZ(transform.rotation.func_195902_c()); m.mul(t); t.setIdentity(); - t.m00 = transform.scale.x; - t.m11 = transform.scale.y; - t.m22 = transform.scale.z; + t.m00 = transform.scale.func_195899_a(); + t.m11 = transform.scale.func_195900_b(); + t.m22 = transform.scale.func_195902_c(); m.mul(t); return m; } diff --git a/src/main/java/net/minecraftforge/common/BiomeDictionary.java b/src/main/java/net/minecraftforge/common/BiomeDictionary.java index 20fe19a6a..9e76e5237 100644 --- a/src/main/java/net/minecraftforge/common/BiomeDictionary.java +++ b/src/main/java/net/minecraftforge/common/BiomeDictionary.java @@ -30,7 +30,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.world.biome.*; import static net.minecraftforge.common.BiomeDictionary.Type.*; import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.registries.ForgeRegistries; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; diff --git a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java index ec2a70abc..f56de6f9f 100644 --- a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java +++ b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java @@ -32,6 +32,11 @@ import java.util.UUID; import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; + import net.minecraft.entity.Entity; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; @@ -50,9 +55,6 @@ import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Property; import net.minecraftforge.common.util.Constants; import net.minecraftforge.fml.server.ServerLifecycleHooks; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.ModContainer; import com.google.common.cache.Cache; @@ -87,11 +89,11 @@ import com.google.common.collect.Sets; * The chunkloading is configurable at runtime. The file "config/forgeChunkLoading.cfg" contains both default configuration for chunkloading, and a sample individual mod * specific override section. * - * @author cpw - * */ public class ForgeChunkManager { + public static Marker CHUNK_MANAGER = MarkerManager.getMarker("CHUNKMANAGER"); + private static Logger LOGGER = LogManager.getLogger(); private static int defaultMaxCount; private static int defaultMaxChunks; private static boolean overridesEnabled; @@ -143,7 +145,7 @@ public class ForgeChunkManager final ImmutableSetMultimap persistentChunksFor = getPersistentChunksFor(world); final ImmutableSet.Builder builder = ImmutableSet.builder(); world.profiler.startSection("forcedChunkLoading"); - builder.addAll(persistentChunksFor.keys().stream().filter(Objects::nonNull).map(input -> world.getChunkFromChunkCoords(input.x, input.z)).iterator()); + builder.addAll(persistentChunksFor.keys().stream().filter(Objects::nonNull).map(input -> world.getChunk(input.x, input.z)).iterator()); world.profiler.endStartSection("regularChunkLoading"); builder.addAll(chunkIterator); world.profiler.endSection(); @@ -265,7 +267,7 @@ public class ForgeChunkManager } else { - FMLLog.log.error("Attempt to create a player ticket without a valid player"); + LOGGER.error(CHUNK_MANAGER, "Attempt to create a player ticket without a valid player"); throw new RuntimeException(); } } @@ -279,7 +281,7 @@ public class ForgeChunkManager { if (depth > getMaxChunkDepthFor(modId) || (depth <= 0 && getMaxChunkDepthFor(modId) > 0)) { - FMLLog.log.warn("The mod {} tried to modify the chunk ticket depth to: {}, its allowed maximum is: {}", modId, depth, getMaxChunkDepthFor(modId)); + LOGGER.warn(CHUNK_MANAGER, "The mod {} tried to modify the chunk ticket depth to: {}, its allowed maximum is: {}", modId, depth, getMaxChunkDepthFor(modId)); } else { @@ -453,7 +455,7 @@ public class ForgeChunkManager try { NBTTagCompound forcedChunkData = CompressedStreamTools.read(chunkLoaderData); - return forcedChunkData.getTagList("TicketList", Constants.NBT.TAG_COMPOUND).tagCount() > 0; + return forcedChunkData.getTagList("TicketList", Constants.NBT.TAG_COMPOUND).size() > 0; } catch (IOException e) { @@ -493,11 +495,11 @@ public class ForgeChunkManager } catch (IOException e) { - FMLLog.log.warn("Unable to read forced chunk data at {} - it will be ignored", chunkLoaderData.getAbsolutePath(), e); + LOGGER.warn(CHUNK_MANAGER, "Unable to read forced chunk data at {} - it will be ignored", chunkLoaderData.getAbsolutePath(), e); return; } NBTTagList ticketList = forcedChunkData.getTagList("TicketList", Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < ticketList.tagCount(); i++) + for (int i = 0; i < ticketList.size(); i++) { NBTTagCompound ticketHolder = ticketList.getCompoundTagAt(i); String modId = ticketHolder.getString("Owner"); @@ -505,18 +507,18 @@ public class ForgeChunkManager if (!isPlayer && !Loader.isModLoaded(modId)) { - FMLLog.log.warn("Found chunkloading data for mod {} which is currently not available or active - it will be removed from the world save", modId); + LOGGER.warn(CHUNK_MANAGER, "Found chunkloading data for mod {} which is currently not available or active - it will be removed from the world save", modId); continue; } if (!isPlayer && !callbacks.containsKey(modId)) { - FMLLog.log.warn("The mod {} has registered persistent chunkloading data but doesn't seem to want to be called back with it - it will be removed from the world save", modId); + LOGGER.warn(CHUNK_MANAGER, "The mod {} has registered persistent chunkloading data but doesn't seem to want to be called back with it - it will be removed from the world save", modId); continue; } NBTTagList tickets = ticketHolder.getTagList("Tickets", Constants.NBT.TAG_COMPOUND); - for (int j = 0; j < tickets.tagCount(); j++) + for (int j = 0; j < tickets.size(); j++) { NBTTagCompound ticket = tickets.getCompoundTagAt(j); modId = ticket.hasKey("ModId") ? ticket.getString("ModId") : modId; @@ -558,14 +560,14 @@ public class ForgeChunkManager // force the world to load the entity's chunk // the load will come back through the loadEntity method and attach the entity // to the ticket - world.getChunkFromChunkCoords(tick.entityChunkX, tick.entityChunkZ); + world.getChunk(tick.entityChunkX, tick.entityChunkZ); } } for (Ticket tick : ImmutableSet.copyOf(pendingEntities.values())) { if (tick.ticketType == Type.ENTITY && tick.entity == null) { - FMLLog.log.warn("Failed to load persistent chunkloading entity {} from store.", pendingEntities.inverse().get(tick)); + LOGGER.warn(CHUNK_MANAGER, "Failed to load persistent chunkloading entity {} from store.", pendingEntities.inverse().get(tick)); loadedTickets.remove(tick.modId, tick); } } @@ -587,7 +589,7 @@ public class ForgeChunkManager } if (tickets.size() > maxTicketLength) { - FMLLog.log.warn("The mod {} has too many open chunkloading tickets {}. Excess will be dropped", modId, tickets.size()); + LOGGER.warn(CHUNK_MANAGER, "The mod {} has too many open chunkloading tickets {}. Excess will be dropped", modId, tickets.size()); tickets.subList(maxTicketLength, tickets.size()).clear(); } ForgeChunkManager.tickets.get(world).putAll(modId, tickets); @@ -645,7 +647,7 @@ public class ForgeChunkManager ModContainer container = getContainer(mod); if (container == null) { - FMLLog.log.warn("Unable to register a callback for an unknown mod {} ({} : {})", mod, mod.getClass().getName(), Integer.toHexString(System.identityHashCode(mod))); + LOGGER.warn(CHUNK_MANAGER, "Unable to register a callback for an unknown mod {} ({} : {})", mod, mod.getClass().getName(), Integer.toHexString(System.identityHashCode(mod))); return; } @@ -703,12 +705,12 @@ public class ForgeChunkManager ModContainer mc = getContainer(mod); if (mc == null) { - FMLLog.log.error("Failed to locate the container for mod instance {} ({} : {})", mod, mod.getClass().getName(), Integer.toHexString(System.identityHashCode(mod))); + LOGGER.error(CHUNK_MANAGER, "Failed to locate the container for mod instance {} ({} : {})", mod, mod.getClass().getName(), Integer.toHexString(System.identityHashCode(mod))); return null; } if (playerTickets.get(player).size()>playerTicketLength) { - FMLLog.log.warn("Unable to assign further chunkloading tickets to player {} (on behalf of mod {})", player, mc.getModId()); + LOGGER.warn(CHUNK_MANAGER, "Unable to assign further chunkloading tickets to player {} (on behalf of mod {})", player, mc.getModId()); return null; } Ticket ticket = new Ticket(mc.getModId(),type,world,player); @@ -730,13 +732,13 @@ public class ForgeChunkManager ModContainer container = getContainer(mod); if (container == null) { - FMLLog.log.error("Failed to locate the container for mod instance {} ({} : {})", mod, mod.getClass().getName(), Integer.toHexString(System.identityHashCode(mod))); + LOGGER.error(CHUNK_MANAGER, "Failed to locate the container for mod instance {} ({} : {})", mod, mod.getClass().getName(), Integer.toHexString(System.identityHashCode(mod))); return null; } String modId = container.getModId(); if (!callbacks.containsKey(modId)) { - FMLLog.log.fatal("The mod {} has attempted to request a ticket without a listener in place", modId); + LOGGER.fatal(CHUNK_MANAGER, "The mod {} has attempted to request a ticket without a listener in place", modId); throw new RuntimeException("Invalid ticket request"); } @@ -746,7 +748,7 @@ public class ForgeChunkManager { if (!warnedMods.contains(modId)) { - FMLLog.log.info("The mod {} has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum: {}", modId, allowedCount); + LOGGER.info(CHUNK_MANAGER, "The mod {} has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum: {}", modId, allowedCount); warnedMods.add(modId); } return null; @@ -810,7 +812,7 @@ public class ForgeChunkManager } if (ticket.isPlayerTicket() ? !playerTickets.containsValue(ticket) : !tickets.get(ticket.world).containsEntry(ticket.modId, ticket)) { - FMLLog.log.fatal("The mod {} attempted to force load a chunk with an invalid ticket. This is not permitted.", ticket.modId); + LOGGER.fatal(CHUNK_MANAGER, "The mod {} attempted to force load a chunk with an invalid ticket. This is not permitted.", ticket.modId); return; } ticket.requestedChunks.add(chunk); @@ -913,7 +915,7 @@ public class ForgeChunkManager for (String modId : ticketSet.keySet()) { NBTTagCompound ticketHolder = new NBTTagCompound(); - ticketList.appendTag(ticketHolder); + ticketList.add(ticketHolder); ticketHolder.setString("Owner", modId); NBTTagList tickets = new NBTTagList(); @@ -939,11 +941,11 @@ public class ForgeChunkManager ticket.setInteger("chunkZ", MathHelper.floor(tick.entity.chunkCoordZ)); ticket.setLong("PersistentIDMSB", tick.entity.getPersistentID().getMostSignificantBits()); ticket.setLong("PersistentIDLSB", tick.entity.getPersistentID().getLeastSignificantBits()); - tickets.appendTag(ticket); + tickets.add(ticket); } else if (tick.ticketType != Type.ENTITY) { - tickets.appendTag(ticket); + tickets.add(ticket); } } } @@ -956,7 +958,7 @@ public class ForgeChunkManager } catch (IOException e) { - FMLLog.log.warn("Unable to write forced chunk data to {} - chunkloading won't work", chunkLoaderData.getAbsolutePath(), e); + LOGGER.warn(CHUNK_MANAGER, "Unable to write forced chunk data to {} - chunkloading won't work", chunkLoaderData.getAbsolutePath(), e); } return false; }); @@ -1025,14 +1027,14 @@ public class ForgeChunkManager private static void loadChunkEntities(Chunk chunk, NBTTagCompound nbt, World world) { NBTTagList entities = nbt.getTagList("Entities", Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < entities.tagCount(); ++i) + for (int i = 0; i < entities.size(); ++i) { AnvilChunkLoader.readChunkEntity(entities.getCompoundTagAt(i), world, chunk); chunk.setHasEntities(true); } NBTTagList tileEntities = nbt.getTagList("TileEntities", Constants.NBT.TAG_COMPOUND); - for (int i = 0; i < tileEntities.tagCount(); ++i) + for (int i = 0; i < tileEntities.size(); ++i) { TileEntity tileEntity = TileEntity.create(world, tileEntities.getCompoundTagAt(i)); if (tileEntity != null) chunk.addTileEntity(tileEntity); @@ -1055,7 +1057,7 @@ public class ForgeChunkManager dest.delete(); } cfgFile.renameTo(dest); - FMLLog.log.error("A critical error occurred reading the forgeChunkLoading.cfg file, defaults will be used - the invalid file is backed up at forgeChunkLoading.cfg.bak", e); + LOGGER.error(CHUNK_MANAGER, "A critical error occurred reading the forgeChunkLoading.cfg file, defaults will be used - the invalid file is backed up at forgeChunkLoading.cfg.bak", e); } syncConfigDefaults(); } @@ -1108,7 +1110,7 @@ public class ForgeChunkManager temp.setMinValue(0); dormantChunkCacheSize = temp.getInt(0); propOrder.add("dormantChunkCacheSize"); - FMLLog.log.info("Configured a dormant chunk cache size of {}", temp.getInt(0)); + LOGGER.info(CHUNK_MANAGER, "Configured a dormant chunk cache size of {}", temp.getInt(0)); temp = config.get("defaults", "asyncChunkLoading", true); temp.setComment("Load chunks asynchronously for players, reducing load on the server thread.\n" + diff --git a/src/main/java/net/minecraftforge/common/ForgeHooks.java b/src/main/java/net/minecraftforge/common/ForgeHooks.java index 0b1c3980b..79094c3d1 100644 --- a/src/main/java/net/minecraftforge/common/ForgeHooks.java +++ b/src/main/java/net/minecraftforge/common/ForgeHooks.java @@ -149,13 +149,13 @@ import net.minecraftforge.fml.common.LoaderState; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher; import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.ConnectionType; -import net.minecraftforge.fml.common.registry.ForgeRegistries; import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.network.ConnectionType; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.relauncher.ReflectionHelper; +import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.IForgeRegistry; import net.minecraftforge.registries.RegistryManager; diff --git a/src/main/java/net/minecraftforge/common/asm/ObjectHolderDefinalize.java b/src/main/java/net/minecraftforge/common/asm/ObjectHolderDefinalize.java new file mode 100644 index 000000000..b4a4aab9e --- /dev/null +++ b/src/main/java/net/minecraftforge/common/asm/ObjectHolderDefinalize.java @@ -0,0 +1,105 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraftforge.common.asm; + +import java.nio.file.Path; +import java.util.List; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; +import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; + +/** + * Removes the final modifier from fields with the @ObjectHolder annotation, prevents the JITer from in lining them so our runtime replacements can work. + * Will also de-finalize all fields in on class level annotations. + */ +public class ObjectHolderDefinalize implements ILaunchPluginService { + + private final String OBJECT_HOLDER = "Lnet/minecraftforge/registries/ObjectHolder;"; //Don't directly reference this to prevent class loading. + + @Override + public String name() { + return "object_holder_definalize"; + } + + @Override public void addResource(Path resource, String name) { } + + @Override public T getExtension() { return null; } // ? + + @Override + public boolean handlesClass(Type classType, boolean isEmpty) + { + return !isEmpty; //Check for annotations? + } + + private boolean hasHolder(List lst) + { + return lst != null && lst.stream().anyMatch(n -> n.desc.equals(OBJECT_HOLDER)); + } + + private String getValue(List lst) + { + AnnotationNode ann = lst.stream().filter(n -> n.desc.equals(OBJECT_HOLDER)).findFirst().get(); + if (ann.values != null) + { + for (int x = 0; x < ann.values.size() - 1; x += 2) { + if (ann.values.get(x).equals("value")) { + return (String)ann.values.get(x + 1); + } + } + } + return null; + } + + @Override + public ClassNode processClass(ClassNode classNode, Type classType) + { + //Must be public static finals, and non-array objects + final int flags = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL; + + //Fix Annotated Fields before injecting from class level + classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.startsWith("L") && hasHolder(f.visibleAnnotations)).forEach(f -> + { + f.access &= ~Opcodes.ACC_FINAL; //Strip final + f.access |= Opcodes.ACC_SYNTHETIC; //Add Synthetic so we can check in runtime. ? Good idea? + }); + + if (hasHolder(classNode.visibleAnnotations)) //Class level, de-finalize all fields and add @ObjectHolder to them! + { + @SuppressWarnings("unused") + String value = getValue(classNode.visibleAnnotations); + classNode.fields.stream().filter(f -> ((f.access & flags) == flags) && f.desc.startsWith("L")).forEach(f -> + { + f.access &= ~Opcodes.ACC_FINAL; + f.access |= Opcodes.ACC_SYNTHETIC; + /*if (!hasHolder(f.visibleAnnotations)) //Add field level annotation, doesn't do anything until after we figure out how ASMDataTable is gatherered + { + if (value == null) + f.visitAnnotation(OBJECT_HOLDER, true); + else + f.visitAnnotation(OBJECT_HOLDER, true).visit("value", value + ":" + f.name.toLowerCase()); + }*/ + }); + } + return classNode; + } + +} diff --git a/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java b/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java new file mode 100644 index 000000000..f6d4a74e9 --- /dev/null +++ b/src/main/java/net/minecraftforge/common/asm/RuntimeEnumExtender.java @@ -0,0 +1,134 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraftforge.common.asm; + +import java.nio.file.Path; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.InstructionAdapter; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodNode; + +import cpw.mods.modlauncher.serviceapi.ILaunchPluginService; + +/** + * Modifies specified enums to allow runtime extension by making the $VALUES field non-final and + * injecting constructor calls which are not valid in normal java code. + */ +public class RuntimeEnumExtender implements ILaunchPluginService { + + private static final Logger LOGGER = LogManager.getLogger(); + private final Type STRING = Type.getType(String.class); + private final Type ARRAY_UTILS = Type.getType("Lorg/apache/commons/lang3/ArrayUtils;"); //Don't directly reference this to prevent class loading. + private final String ADD_DESC = Type.getMethodDescriptor(Type.getType(Object[].class), Type.getType(Object[].class), Type.getType(Object.class)); + private final Type ENUM_HELPER = Type.getType("Lnet/minecraftforge/common/util/EnumHelper;"); //Again, not direct reference to prevent class loading. + private final String CLEAN_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Class.class)); + + @Override + public String name() { + return "runtime_enum_extender"; + } + + @Override public void addResource(Path resource, String name) { } + + @Override public T getExtension() { return null; } // ? + + @Override + public boolean handlesClass(Type classType, boolean isEmpty) + { + return !isEmpty; //Any way to determine if its a enum at this level? + } + + @Override + public ClassNode processClass(ClassNode classNode, Type classType) + { + if ((classNode.access & Opcodes.ACC_ENUM) == 0) + return classNode; + + Type array = Type.getType("[" + classType.getInternalName()); + final int flags = Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC; + + FieldNode values = classNode.fields.stream().filter(f -> f.desc.contentEquals(array.getDescriptor()) && ((f.access & flags) == flags)).findFirst().orElse(null); + //Static methods named "create", with first argument as a string, and returning this type + classNode.methods.stream().filter(m -> ((m.access & Opcodes.ACC_STATIC) != 0) && m.name.equals("create") && Type.getReturnType(m.desc).equals(classType)).forEach(mtd -> + { + Type[] args = Type.getArgumentTypes(mtd.desc); + if (args.length == 0 || !args[0].equals(STRING)) + return; + + Type[] ctrArgs = new Type[args.length + 1]; + ctrArgs[0] = STRING; + ctrArgs[1] = Type.INT_TYPE; + for (int x = 1; x < args.length; x++) + ctrArgs[1 + x] = args[x]; + + String desc = Type.getMethodDescriptor(Type.VOID_TYPE, ctrArgs); + + MethodNode ctr = classNode.methods.stream().filter(m -> m.name.equals("") && m.desc.equals(desc)).findFirst().orElse(null); + if (ctr == null) + { + LOGGER.error("Enum has create method with no matching constructor:"); + LOGGER.error(" Target: " + desc); + classNode.methods.stream().filter(m -> m.name.equals("")).forEach(m -> LOGGER.error(" :" + m.desc)); + throw new IllegalStateException("Enum has create method with no matching constructor: " + desc); + } + + if (values == null) + { + LOGGER.error("Enum has create method but we could not find $VALUES:"); + classNode.fields.stream().filter(f -> (f.access & Opcodes.ACC_STATIC) != 0).forEach(m -> LOGGER.error(" " + m.name + " " + m.desc)); + throw new IllegalStateException("Enum has create method but we could not find $VALUES"); + } + + values.access &= values.access & ~Opcodes.ACC_FINAL; //Strip the final so JITer doesn't inline things. + + mtd.instructions.clear(); + InstructionAdapter ins = new InstructionAdapter(mtd); + //ret = new ThisType(name, VALUES.length + 1, args..) + ins.anew(classType); + ins.dup(); + ins.load(0, STRING); + ins.getstatic(classType.getInternalName(), values.name, values.desc); + ins.iconst(1); + ins.add(Type.INT_TYPE); + for (int x = 1; x < args.length; x++) + ins.load(x, args[x]); + ins.invokespecial(classType.getDescriptor(), "", desc, false); + ins.store(1, classType); + // VALUES = ArrayUtils.add(VALUES, ret) + ins.getstatic(classType.getInternalName(), values.name, values.desc); + ins.load(1, classType); + ins.invokestatic(ARRAY_UTILS.getDescriptor(), "add", ADD_DESC, false); + ins.checkcast(array); + ins.putstatic(classType.getInternalName(), values.name, values.desc); + //EnumHelper.cleanEnumCache(ThisType.class) + ins.visitLdcInsn(classType); + ins.invokestatic(ENUM_HELPER.getInternalName(), "cleanEnumCache", CLEAN_DESC, false); + //return ret + ins.load(1, classType); + ins.areturn(classType); + }); + return classNode; + } + +} diff --git a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java index d82108f51..f937ddfe8 100644 --- a/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java +++ b/src/main/java/net/minecraftforge/common/crafting/CraftingHelper.java @@ -65,11 +65,11 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.JsonUtils; import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.registry.ForgeRegistries; import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.OreIngredient; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; +import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistry; import net.minecraftforge.registries.GameData; import net.minecraftforge.registries.RegistryManager; diff --git a/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java b/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java index 906279e5a..6d6cda0f3 100644 --- a/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java +++ b/src/main/java/net/minecraftforge/common/util/BlockSnapshot.java @@ -29,7 +29,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.registries.ForgeRegistries; import javax.annotation.Nullable; diff --git a/src/main/java/net/minecraftforge/common/util/EnumHelper.java b/src/main/java/net/minecraftforge/common/util/EnumHelper.java index 7d885c1d9..09afd0019 100644 --- a/src/main/java/net/minecraftforge/common/util/EnumHelper.java +++ b/src/main/java/net/minecraftforge/common/util/EnumHelper.java @@ -27,207 +27,21 @@ import com.google.common.base.Predicate; import com.google.common.collect.Lists; import net.minecraftforge.fml.common.EnhancedRuntimeException; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraft.block.BlockPressurePlate.Sensitivity; -import net.minecraft.block.material.Material; -import net.minecraft.enchantment.EnumEnchantmentType; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EnumCreatureAttribute; -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.entity.item.EntityPainting.EnumArt; -import net.minecraft.entity.passive.HorseArmorType; -import net.minecraft.entity.passive.IAnimals; -import net.minecraft.entity.player.EntityPlayer.SleepResult; -import net.minecraft.item.EnumAction; -import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; -import net.minecraft.item.Item.ToolMaterial; -import net.minecraft.item.ItemArmor.ArmorMaterial; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextFormatting; -import net.minecraft.world.EnumSkyBlock; -import net.minecraft.world.IBlockAccess; -import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door; -import net.minecraftforge.classloading.FMLForgePlugin; import org.apache.commons.lang3.ArrayUtils; import javax.annotation.Nullable; public class EnumHelper { - private static Object reflectionFactory = null; - private static Method newConstructorAccessor = null; - private static Method newInstance = null; - private static Method newFieldAccessor = null; - private static Method fieldAccessorSet = null; - private static boolean isSetup = false; - - //Some enums are decompiled with extra arguments, so lets check for that - private static Class[][] commonTypes = - { - {EnumAction.class}, - {ArmorMaterial.class, String.class, int.class, int[].class, int.class, SoundEvent.class, float.class}, - {EnumArt.class, String.class, int.class, int.class, int.class, int.class}, - {EnumCreatureAttribute.class}, - {EnumCreatureType.class, Class.class, int.class, Material.class, boolean.class, boolean.class}, - {Door.class}, - {EnumEnchantmentType.class, Predicate.class}, - {Sensitivity.class}, - {RayTraceResult.Type.class}, - {EnumSkyBlock.class, int.class}, - {SleepResult.class}, - {ToolMaterial.class, int.class, int.class, float.class, float.class, int.class}, - {EnumRarity.class, TextFormatting.class, String.class}, - {HorseArmorType.class, String.class, int.class}, - {EntityLiving.SpawnPlacementType.class, BiPredicate.class} - }; - - @Nullable - public static EnumAction addAction(String name) - { - return addEnum(EnumAction.class, name); - } - @Nullable - public static ArmorMaterial addArmorMaterial(String name, String textureName, int durability, int[] reductionAmounts, int enchantability, SoundEvent soundOnEquip, float toughness) - { - return addEnum(ArmorMaterial.class, name, textureName, durability, reductionAmounts, enchantability, soundOnEquip, toughness); - } - @Nullable - public static EnumArt addArt(String name, String tile, int sizeX, int sizeY, int offsetX, int offsetY) - { - return addEnum(EnumArt.class, name, tile, sizeX, sizeY, offsetX, offsetY); - } - @Nullable - public static EnumCreatureAttribute addCreatureAttribute(String name) - { - return addEnum(EnumCreatureAttribute.class, name); - } - @Nullable - public static EnumCreatureType addCreatureType(String name, Class typeClass, int maxNumber, Material material, boolean peaceful, boolean animal) - { - return addEnum(EnumCreatureType.class, name, typeClass, maxNumber, material, peaceful, animal); - } - @Nullable - public static Door addDoor(String name) - { - return addEnum(Door.class, name); - } - @Nullable - public static EnumEnchantmentType addEnchantmentType(String name, Predicate delegate) - { - return addEnum(EnumEnchantmentType.class, name, delegate); - } - @Nullable - public static Sensitivity addSensitivity(String name) - { - return addEnum(Sensitivity.class, name); - } - @Nullable - public static RayTraceResult.Type addMovingObjectType(String name) - { - return addEnum(RayTraceResult.Type.class, name); - } - @Nullable - public static EnumSkyBlock addSkyBlock(String name, int lightValue) - { - return addEnum(EnumSkyBlock.class, name, lightValue); - } - @Nullable - public static SleepResult addStatus(String name) - { - return addEnum(SleepResult.class, name); - } - @Nullable - public static ToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability) - { - return addEnum(ToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability); - } - @Nullable - public static EnumRarity addRarity(String name, TextFormatting color, String displayName) - { - return addEnum(EnumRarity.class, name, color, displayName); - } - - @Nullable - public static EntityLiving.SpawnPlacementType addSpawnPlacementType(String name, BiPredicate predicate) - { - return addEnum(EntityLiving.SpawnPlacementType.class, name, predicate); - } - - /** - * - * @param name the name of the new {@code HorseArmorType} - * @param textureLocation the path to the texture for this armor type. It must follow the format domain:path and be relative to the assets folder. - * @param armorStrength how much protection this armor type should give - * @return the new {@code HorseArmorType}, or null if it could not be created - */ - @Nullable - public static HorseArmorType addHorseArmor(String name, String textureLocation, int armorStrength) - { - return addEnum(HorseArmorType.class, name, textureLocation, armorStrength); - } - - private static void setup() - { - if (isSetup) - { - return; - } - - try - { - Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory"); - reflectionFactory = getReflectionFactory.invoke(null); - newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", Constructor.class); - newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", Object[].class); - newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class); - fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class); - } - catch (Exception e) - { - FMLLog.log.error("Error setting up EnumHelper.", e); - } - - isSetup = true; - } - - /* + /* * Everything below this is found at the site below, and updated to be able to compile in Eclipse/Java 1.6+ * Also modified for use in decompiled code. * Found at: http://niceideas.ch/roller2/badtrash/entry/java_create_enum_instances_dynamically */ - private static Object getConstructorAccessor(Class enumClass, Class[] additionalParameterTypes) throws Exception - { - Class[] parameterTypes = new Class[additionalParameterTypes.length + 2]; - parameterTypes[0] = String.class; - parameterTypes[1] = int.class; - System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length); - return newConstructorAccessor.invoke(reflectionFactory, enumClass.getDeclaredConstructor(parameterTypes)); - } private static < T extends Enum> T makeEnum(Class enumClass, @Nullable String value, int ordinal, Class[] additionalTypes, @Nullable Object[] additionalValues) throws Exception { - int additionalParamsCount = additionalValues == null ? 0 : additionalValues.length; - Object[] params = new Object[additionalParamsCount + 2]; - params[0] = value; - params[1] = ordinal; - if (additionalValues != null) - { - System.arraycopy(additionalValues, 0, params, 2, additionalValues.length); - } - return enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[] {params})); - } - - public static void setFailsafeFieldValue(Field field, @Nullable Object target, @Nullable Object value) throws Exception - { - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false); - fieldAccessorSet.invoke(fieldAccessor, target, value); + //new Enum(name, values.size() + 1, params) } private static void blankField(Class enumClass, String fieldName) throws Exception @@ -237,190 +51,35 @@ public class EnumHelper if (field.getName().contains(fieldName)) { field.setAccessible(true); - setFailsafeFieldValue(field, enumClass, null); + field.set(enumClass, null); break; } } } - private static void cleanEnumCache(Class enumClass) throws Exception + //Class holds caches of the enum constants used for Enum.valueOf() and reflection magic. So we need to invalidate those caches when we add something new. They will automtically be re-built. + public static void cleanEnumCache(Class enumClass) throws Exception { blankField(enumClass, "enumConstantDirectory"); blankField(enumClass, "enumConstants"); } - @Nullable - private static > T addEnum(Class enumType, String enumName, Object... paramValues) - { - setup(); - return addEnum(commonTypes, enumType, enumName, paramValues); - } - - @Nullable - protected static > T addEnum(Class[][] map, Class enumType, String enumName, Object... paramValues) - { - for (Class[] lookup : map) - { - if (lookup[0] == enumType) - { - Class[] paramTypes = new Class[lookup.length - 1]; - if (paramTypes.length > 0) - { - System.arraycopy(lookup, 1, paramTypes, 0, paramTypes.length); - } - return addEnum(enumType, enumName, paramTypes, paramValues); - } - } - return null; - } - - //Tests an enum is compatible with these args, throws an error if not. - public static void testEnum(Class> enumType, Class[] paramTypes) - { - addEnum(true, enumType, null, paramTypes, (Object[])null); - } - - @Nullable - public static > T addEnum(Class enumType, String enumName, Class[] paramTypes, Object... paramValues) - { - return addEnum(false, enumType, enumName, paramTypes, paramValues); - } - @SuppressWarnings({ "unchecked", "serial" }) @Nullable - private static > T addEnum(boolean test, final Class enumType, @Nullable String enumName, final Class[] paramTypes, @Nullable Object[] paramValues) + private static & IExpandableEnum> T addEnum(boolean test, final Class enumType, T newValue) { - if (!isSetup) - { - setup(); - } - - Field valuesField = null; - Field[] fields = enumType.getDeclaredFields(); - - for (Field field : fields) - { - String name = field.getName(); - if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards - { - valuesField = field; - break; - } - } - - int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/; - if (valuesField == null) - { - String valueType = String.format("[L%s;", enumType.getName().replace('.', '/')); - - for (Field field : fields) - { - if ((field.getModifiers() & flags) == flags && - field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't.. - { - valuesField = field; - break; - } - } - } - - if (valuesField == null) - { - final List lines = Lists.newArrayList(); - lines.add(String.format("Could not find $VALUES field for enum: %s", enumType.getName())); - lines.add(String.format("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF)); - lines.add(String.format("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0'))); - lines.add( "Fields:"); - for (Field field : fields) - { - String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0'); - lines.add(String.format(" %s %s: %s", mods, field.getName(), field.getType().getName())); - } - - for (String line : lines) - FMLLog.log.fatal(line); - - if (test) - { - throw new EnhancedRuntimeException("Could not find $VALUES field for enum: " + enumType.getName()) - { - @Override - protected void printStackTrace(WrappedPrintStream stream) - { - for (String line : lines) - stream.println(line); - } - }; - } - return null; - } - - if (test) - { - Object ctr = null; - Exception ex = null; - try - { - ctr = getConstructorAccessor(enumType, paramTypes); - } - catch (Exception e) - { - ex = e; - } - if (ctr == null || ex != null) - { - throw new EnhancedRuntimeException(String.format("Could not find constructor for Enum %s", enumType.getName()), ex) - { - private String toString(Class[] cls) - { - StringBuilder b = new StringBuilder(); - for (int x = 0; x < cls.length; x++) - { - b.append(cls[x].getName()); - if (x != cls.length - 1) - b.append(", "); - } - return b.toString(); - } - @Override - protected void printStackTrace(WrappedPrintStream stream) - { - stream.println("Target Arguments:"); - stream.println(" java.lang.String, int, " + toString(paramTypes)); - stream.println("Found Constructors:"); - for (Constructor ctr : enumType.getDeclaredConstructors()) - { - stream.println(" " + toString(ctr.getParameterTypes())); - } - } - }; - } - return null; - } - - valuesField.setAccessible(true); - try { - T[] previousValues = (T[])valuesField.get(enumType); + T[] previousValues = enumType.getEnumConstants(); T newValue = makeEnum(enumType, enumName, previousValues.length, paramTypes, paramValues); - setFailsafeFieldValue(valuesField, null, ArrayUtils.add(previousValues, newValue)); + newValue.__set_values__(ArrayUtils.add(previousValues, newValue)); cleanEnumCache(enumType); return newValue; } catch (Exception e) { - FMLLog.log.error("Error adding enum with EnumHelper.", e); throw new RuntimeException(e); } } - - static - { - if (!isSetup) - { - setup(); - } - } } diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java deleted file mode 100644 index 46f367d1c..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/ByteBufferSeekableSource.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * ByteArraySeekableSource.java - * - * Created on May 17, 2006, 12:41 PM - * Copyright (c) 2006 Heiko Klein - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.IOException; -import java.nio.ByteBuffer; - -/** - * Wraps a byte buffer as a source - */ -public class ByteBufferSeekableSource implements SeekableSource { - - private ByteBuffer bb; - private ByteBuffer cur; - - /** - * Constructs a new ByteArraySeekableSource. - */ - public ByteBufferSeekableSource(byte[] source) { - this(ByteBuffer.wrap(source)); - } - - /** - * Constructs a new ByteArraySeekableSource. - */ - public ByteBufferSeekableSource(ByteBuffer bb) { - if (bb == null) - throw new NullPointerException("bb"); - this.bb = bb; - bb.rewind(); - try { - seek(0); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void seek(long pos) throws IOException { - cur = bb.slice(); - if (pos > cur.limit()) - throw new IOException("pos " + pos + " cannot seek " + cur.limit()); - cur.position((int) pos); - } - - @Override - public int read(ByteBuffer dest) throws IOException { - if (!cur.hasRemaining()) - return -1; - int c = 0; - while (cur.hasRemaining() && dest.hasRemaining()) { - dest.put(cur.get()); - c++; - } - return c; - } - - @Override - public void close() throws IOException { - bb = null; - cur = null; - } - - /** - * Returns a debug String. - */ - @Override - public String toString() - { - return "BBSeekable" + - " bb=" + this.bb.position() + "-" + bb.limit() + - " cur=" + this.cur.position() + "-" + cur.limit() + - ""; - } - -} diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java deleted file mode 100644 index 55cc03396..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Checksum.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * - * Copyright (c) 2001 Torgeir Veimo - * Copyright (c) 2002 Nicolas PERIDONT - * Copyright (c) 2006 Heiko Klein - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.util.Map; - -import com.google.common.collect.Maps; - -/** - * Checksum computation class. - */ -public class Checksum { - - static final boolean debug = false; - - private Map checksums = Maps.newHashMap(); - - private static final char single_hash[] = { - /* Random numbers generated using SLIB's pseudo-random number generator. */ - 0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46, - 0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602, - 0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6, - 0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a, - 0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58, - 0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b, - 0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94, - 0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176, - 0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743, - 0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6, - 0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227, - 0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d, - 0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a, - 0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31, - 0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9, - 0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6, - 0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f, - 0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f, - 0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49, - 0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037, - 0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad, - 0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f, - 0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d, - 0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b, - 0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624, - 0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272, - 0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806, - 0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050, - 0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113, - 0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2, - 0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25, - 0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5 - }; - - /** - * Initialize checksums for source. The checksum for the chunkSize bytes at offset - * chunkSize * i is inserted into a hash map. - */ - public Checksum(SeekableSource source, int chunkSize) throws IOException { - ByteBuffer bb = ByteBuffer.allocate(chunkSize * 2); - int count = 0; - while (true) { - source.read(bb); - bb.flip(); - if (bb.remaining() < chunkSize) - break; - while (bb.remaining() >= chunkSize) { - long queryChecksum = queryChecksum0(bb, chunkSize); - checksums.put(queryChecksum, count++); - } - bb.compact(); - } - } - - /** - * Finds the checksum computed from the buffer. - * Marks, gets, then resets the buffer. - */ - public static long queryChecksum(ByteBuffer bb, int len) { - bb.mark(); - long sum = queryChecksum0(bb, len); - bb.reset(); - return sum; - } - - private static long queryChecksum0(ByteBuffer bb, int len) { - int high = 0; int low = 0; - for (int i = 0; i < len; i++) { - low += single_hash[bb.get()+128]; - high += low; - } - return ((high & 0xffff) << 16) | (low & 0xffff); - } - - /** - * Increments a checksum. - * @param checksum initial checksum - * @param out byte leaving view - * @param in byte entering view - * @param chunkSize size of chunks - * @return new checksum - */ - public static long incrementChecksum(long checksum, byte out, byte in, int chunkSize) { - char old_c = single_hash[out+128]; - char new_c = single_hash[in+128]; - int low = ((int)((checksum) & 0xffff) - old_c + new_c) & 0xffff; - int high = ((int)((checksum) >> 16) - (old_c * chunkSize) + low) & 0xffff; - return (high << 16) | (low & 0xffff); - } - - /** - * 256 random hash values. - */ - public static char[] getSingleHash() { - return single_hash; - } - - /** - * Finds the index of a checksum. - */ - public int findChecksumIndex(long hashf) { - if (!checksums.containsKey(hashf)) - return -1; - return checksums.get(hashf); - } - - /** - * Returns a debug String. - */ - @Override - public String toString() - { - return super.toString() + - " checksums=" + this.checksums; - } - - -} diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java deleted file mode 100644 index 26d879d04..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DebugDiffWriter.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * Copyright (c) 2001 Torgeir Veimo - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -/** - * For debugging patch generation. - */ -public class DebugDiffWriter implements DiffWriter { - - private ByteArrayOutputStream os = new ByteArrayOutputStream(); - - /** - * Constructs a new DebugDiffWriter. - */ - public DebugDiffWriter() {} - - @Override - public void addCopy(long offset, int length) throws IOException { - if (os.size() > 0) - writeBuf(); - System.err.println("COPY off: " + offset + ", len: " + length); - } - - @Override - public void addData(byte b) throws IOException { - os.write(b); - writeBuf(); - } - private void writeBuf() { - System.err.print("DATA: "); - byte[] ba = os.toByteArray(); - for (int ix = 0; ix < ba.length; ix++) { - if (ba[ix] == '\n') - System.err.print("\\n"); - else - System.err.print(String.valueOf((char) ba[ix])); - //System.err.print("0x" + Integer.toHexString(buf[ix]) + " "); // hex output - } - System.err.println(""); - os.reset(); - } - - @Override - public void flush() throws IOException { - System.err.println("FLUSH"); - } - @Override - public void close() throws IOException { - System.err.println("CLOSE"); - } - -} - diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java deleted file mode 100644 index 60cc2d56f..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/Delta.java +++ /dev/null @@ -1,447 +0,0 @@ - /* - * - * Copyright (c) 2001 Torgeir Veimo - * Copyright (c) 2002 Nicolas PERIDONT - * Bug Fixes: Daniel Morrione dan@morrione.net - * Copyright (c) 2006 Heiko Klein - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Change Log: - * iiimmddyyn nnnnn Description - * ---------- ----- ------------------------------------------------------- - * gls100603a Fixes from Torgeir Veimo and Dan Morrione - * gls110603a Stream not being closed thus preventing a file from - * being subsequently deleted. - * gls031504a Error being written to stderr rather than throwing exception - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; -import java.nio.channels.Channels; -import java.nio.channels.ReadableByteChannel; - -/** - * Class for computing deltas against a source. - * The source file is read by blocks and a hash is computed per block. - * Then the target is scanned for matching blocks. - *

- * This class is not thread safe. Use one instance per thread. - *

- * This class should support files over 4GB in length, although you must - * use a larger checksum size, such as 1K, as all checksums use "int" indexing. - * Newer versions may eventually support paging in/out of checksums. - */ -public class Delta { - - /** - * Debug flag. - */ - final static boolean debug = false; - - /** - * Default size of 16. - * For "Lorem ipsum" text files (see the tests) the ideal size is about 14. - * Any smaller and the patch size becomes actually be larger. - *

- * Use a size like 64 or 128 for large files. - */ - public static final int DEFAULT_CHUNK_SIZE = 1<<4; - - /** - * Chunk Size. - */ - private int S; - - private SourceState source; - private TargetState target; - private DiffWriter output; - - /** - * Constructs a new Delta. - * In the future, additional constructor arguments will set the algorithm details. - */ - public Delta() { - setChunkSize(DEFAULT_CHUNK_SIZE); - } - - /** - * Sets the chunk size used. - * Larger chunks are faster and use less memory, but create larger patches - * as well. - * - * @param size - */ - public void setChunkSize(int size) { - if (size <= 0) - throw new IllegalArgumentException("Invalid size"); - S = size; - } - - /** - * Compares the source bytes with target bytes, writing to output. - */ - public void compute(byte source[], byte target[], OutputStream output) - throws IOException { - compute(new ByteBufferSeekableSource(source), - new ByteArrayInputStream(target), - new GDiffWriter(output)); - } - - /** - * Compares the source bytes with target bytes, returning output. - */ - public byte[] compute(byte source[], byte target[]) - throws IOException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - compute(source, target, os); - return os.toByteArray(); - } - - /** - * Compares the source bytes with target input, writing to output. - */ - public void compute(byte[] sourceBytes, InputStream inputStream, - DiffWriter diffWriter) throws IOException - { - compute(new ByteBufferSeekableSource(sourceBytes), - inputStream, diffWriter); - } - - /** - * Compares the source file with a target file, writing to output. - * - * @param output will be closed - */ - public void compute(File sourceFile, File targetFile, DiffWriter output) - throws IOException { - RandomAccessFileSeekableSource source = new RandomAccessFileSeekableSource(new RandomAccessFile(sourceFile, "r")); - InputStream is = new BufferedInputStream(new FileInputStream(targetFile)); - try { - compute(source, is, output); - } finally { - source.close(); - is.close(); - } - } - - /** - * Compares the source with a target, writing to output. - * - * @param output will be closed - */ - public void compute(SeekableSource seekSource, InputStream targetIS, DiffWriter output) - throws IOException { - - if (debug) { - debug("using match length S = " + S); - } - - source = new SourceState(seekSource); - target = new TargetState(targetIS); - this.output = output; - if (debug) - debug("checksums " + source.checksum); - - while (!target.eof()) { - debug("!target.eof()"); - int index = target.find(source); - if (index != -1) { - if (debug) - debug("found hash " + index); - long offset = (long)index * S; - source.seek(offset); - int match = target.longestMatch(source); - if (match >= S) { - if (debug) - debug("output.addCopy("+offset+","+match+")"); - output.addCopy(offset, match); - } else { - // move the position back according to how much we can't copy - target.tbuf.position(target.tbuf.position() - match); - addData(); - } - } else { - addData(); - } - } - output.close(); - } - - private void addData() throws IOException { - int i = target.read(); - if (debug) - debug("addData " + Integer.toHexString(i)); - if (i == -1) - return; - output.addData((byte)i); - } - - class SourceState { - - private Checksum checksum; - private SeekableSource source; - - public SourceState(SeekableSource source) throws IOException { - checksum = new Checksum(source, S); - this.source = source; - source.seek(0); - } - - public void seek(long index) throws IOException { - source.seek(index); - } - - /** - * Returns a debug String. - */ - @Override - public String toString() - { - return "Source"+ - " checksum=" + this.checksum + - " source=" + this.source + - ""; - } - - } - - class TargetState { - - private ReadableByteChannel c; - private ByteBuffer tbuf = ByteBuffer.allocate(blocksize()); - private ByteBuffer sbuf = ByteBuffer.allocate(blocksize()); - private long hash; - private boolean hashReset = true; - private boolean eof; - - TargetState(InputStream targetIS) throws IOException { - c = Channels.newChannel(targetIS); - tbuf.limit(0); - } - - private int blocksize() { - return Math.min(1024 * 16, S * 4); - } - - /** - * Returns the index of the next N bytes of the stream. - */ - public int find(SourceState source) throws IOException { - if (eof) - return -1; - sbuf.clear(); - sbuf.limit(0); - if (hashReset) { - debug("hashReset"); - while (tbuf.remaining() < S) { - tbuf.compact(); - int read = c.read(tbuf); - tbuf.flip(); - if (read == -1) { - debug("target ending"); - return -1; - } - } - hash = Checksum.queryChecksum(tbuf, S); - hashReset = false; - } - if (debug) - debug("hash " + hash + " " + dump()); - return source.checksum.findChecksumIndex(hash); - } - - public boolean eof() { - return eof; - } - - /** - * Reads a byte. - * @throws IOException - */ - public int read() throws IOException { - if (tbuf.remaining() <= S) { - readMore(); - if (!tbuf.hasRemaining()) { - eof = true; - return -1; - } - } - byte b = tbuf.get(); - if (tbuf.remaining() >= S) { - byte nchar = tbuf.get( tbuf.position() + S -1 ); - hash = Checksum.incrementChecksum(hash, b, nchar, S); - } else { - debug("out of char"); - } - return b & 0xFF; - } - - /** - * Returns the longest match length at the source location. - */ - public int longestMatch(SourceState source) throws IOException { - debug("longestMatch"); - int match = 0; - hashReset = true; - while (true) { - if (!sbuf.hasRemaining()) { - sbuf.clear(); - int read = source.source.read(sbuf); - sbuf.flip(); - if (read == -1) - return match; - } - if (!tbuf.hasRemaining()) { - readMore(); - if (!tbuf.hasRemaining()) { - debug("target ending"); - eof = true; - return match; - } - } - if (sbuf.get() != tbuf.get()) { - tbuf.position(tbuf.position() - 1); - return match; - } - match++; - } - } - - private void readMore() throws IOException { - if (debug) - debug("readMore " + tbuf); - tbuf.compact(); - c.read(tbuf); - tbuf.flip(); - } - - void hash() { - hash = Checksum.queryChecksum(tbuf, S); - } - - /** - * Returns a debug String. - */ - @Override - public String toString() - { - return "Target[" + - " targetBuff=" + dump() + // this.tbuf + - " sourceBuff=" + this.sbuf + - " hashf=" + this.hash + - " eof=" + this.eof + - "]"; - } - - private String dump() { return dump(tbuf); } - - private String dump(ByteBuffer bb) { - return getTextDump(bb); - } - - private void append(StringBuffer sb, int value) { - char b1 = (char)((value >> 4) & 0x0F); - char b2 = (char)((value) & 0x0F); - sb.append( Character.forDigit(b1, 16) ); - sb.append( Character.forDigit(b2, 16) ); - } - - public String getTextDump(ByteBuffer bb) - { - StringBuffer sb = new StringBuffer(bb.remaining() * 2); - bb.mark(); - while (bb.hasRemaining()) { - int val = bb.get(); - if (val > 32 && val < 127) - sb.append(" ").append((char)val); - else - append(sb, val); - } - bb.reset(); - return sb.toString(); - } - - } - - /** - * Creates a patch using file names. - */ - public static void main(String argv[]) throws Exception { - if (argv.length != 3) { - System.err.println("usage Delta [-d] source target [output]"); - System.err.println("either -d or an output filename must be specified."); - System.err.println("aborting.."); - return; - } - DiffWriter output = null; - File sourceFile = null; - File targetFile = null; - if (argv[0].equals("-d")) { - sourceFile = new File(argv[1]); - targetFile = new File(argv[2]); - output = new DebugDiffWriter(); - } else { - sourceFile = new File(argv[0]); - targetFile = new File(argv[1]); - output = - new GDiffWriter( - new DataOutputStream( - new BufferedOutputStream( - new FileOutputStream(new File(argv[2]))))); - } - - if (sourceFile.length() > Integer.MAX_VALUE - || targetFile.length() > Integer.MAX_VALUE) { - System.err.println( - "source or target is too large, max length is " - + Integer.MAX_VALUE); - System.err.println("aborting.."); - output.close(); - return; - } - - Delta d = new Delta(); - d.compute(sourceFile, targetFile, output); - - output.flush(); - output.close(); - if (debug) //gls031504a - System.out.println("finished generating delta"); - } - - private void debug(String s) { - if (debug) - System.err.println(s); - } - -} diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java deleted file mode 100644 index a2534e346..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/DiffWriter.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * - * Copyright (c) 2001 Torgeir Veimo - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.Closeable; -import java.io.IOException; - -/** - * Interface for DIFF writers. - */ -public interface DiffWriter extends Closeable { - - /** - * Add a GDIFF copy instruction. - */ - public void addCopy(long offset, int length) throws IOException; - - /** - * Add a GDIFF data instruction. - * Implementors should buffer the data. - */ - public void addData(byte b) throws IOException; - - /** - * Flushes to output, e.g. any data added. - */ - public void flush() throws IOException; - - /** - * Closes this stream. - * Note that {@link DiffWriter} will invoke this method at the end. - */ - @Override - public void close() throws IOException; -} - diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java deleted file mode 100644 index 32aca4873..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffPatcher.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * - * Copyright (c) 2001 Torgeir Veimo - * Copyright (c) 2006 Heiko Klein - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import org.apache.commons.io.IOUtils; - -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.COPY_INT_INT; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.COPY_INT_UBYTE; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.COPY_INT_USHORT; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.COPY_LONG_INT; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.COPY_USHORT_INT; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.COPY_USHORT_UBYTE; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.COPY_USHORT_USHORT; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.DATA_INT; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.DATA_MAX; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.DATA_USHORT; -import static net.minecraftforge.fml.repackage.com.nothome.delta.GDiffWriter.EOF; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; - -/** - * This class patches an input file with a GDIFF patch file. - * - * The patch file follows the GDIFF file specification available at - * - * http://www.w3.org/TR/NOTE-gdiff-19970901.html. - */ -public class GDiffPatcher { - - private ByteBuffer buf = ByteBuffer.allocate(1024); - private byte buf2[] = buf.array(); - - /** - * Constructs a new GDiffPatcher. - */ - public GDiffPatcher() { - } - - /** - * Patches to an output file. - */ - public void patch(File sourceFile, File patchFile, File outputFile) - throws IOException - { - RandomAccessFileSeekableSource source =new RandomAccessFileSeekableSource(new RandomAccessFile(sourceFile, "r")); - InputStream patch = null; - OutputStream output = null; - try { - patch = new FileInputStream(patchFile); - output = new FileOutputStream(outputFile); - patch(source, patch, output); - } finally { - IOUtils.closeQuietly(source); - IOUtils.closeQuietly(patch); - IOUtils.closeQuietly(output); - } - } - - /** - * Patches to an output stream. - */ - public void patch(byte[] source, InputStream patch, OutputStream output) throws IOException { - patch(new ByteBufferSeekableSource(source), patch, output); - } - - /** - * Patches in memory, returning the patch result. - */ - public byte[] patch(byte[] source, byte[] patch) throws IOException { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - patch(source, new ByteArrayInputStream(patch), os); - return os.toByteArray(); - } - - /** - * Patches to an output stream. - */ - public void patch(SeekableSource source, InputStream patch, OutputStream out) throws IOException { - - DataOutputStream outOS = new DataOutputStream(out); - DataInputStream patchIS = new DataInputStream(patch); - - // the magic string is 'd1 ff d1 ff' + the version number - if (patchIS.readUnsignedByte() != 0xd1 || - patchIS.readUnsignedByte() != 0xff || - patchIS.readUnsignedByte() != 0xd1 || - patchIS.readUnsignedByte() != 0xff || - patchIS.readUnsignedByte() != 0x04) { - - throw new PatchException("magic string not found, aborting!"); - } - - while (true) { - int command = patchIS.readUnsignedByte(); - if (command == EOF) - break; - int length; - int offset; - - if (command <= DATA_MAX) { - append(command, patchIS, outOS); - continue; - } - - switch (command) { - case DATA_USHORT: // ushort, n bytes following; append - length = patchIS.readUnsignedShort(); - append(length, patchIS, outOS); - break; - case DATA_INT: // int, n bytes following; append - length = patchIS.readInt(); - append(length, patchIS, outOS); - break; - case COPY_USHORT_UBYTE: - offset = patchIS.readUnsignedShort(); - length = patchIS.readUnsignedByte(); - copy(offset, length, source, outOS); - break; - case COPY_USHORT_USHORT: - offset = patchIS.readUnsignedShort(); - length = patchIS.readUnsignedShort(); - copy(offset, length, source, outOS); - break; - case COPY_USHORT_INT: - offset = patchIS.readUnsignedShort(); - length = patchIS.readInt(); - copy(offset, length, source, outOS); - break; - case COPY_INT_UBYTE: - offset = patchIS.readInt(); - length = patchIS.readUnsignedByte(); - copy(offset, length, source, outOS); - break; - case COPY_INT_USHORT: - offset = patchIS.readInt(); - length = patchIS.readUnsignedShort(); - copy(offset, length, source, outOS); - break; - case COPY_INT_INT: - offset = patchIS.readInt(); - length = patchIS.readInt(); - copy(offset, length, source, outOS); - break; - case COPY_LONG_INT: - long loffset = patchIS.readLong(); - length = patchIS.readInt(); - copy(loffset, length, source, outOS); - break; - default: - throw new IllegalStateException("command " + command); - } - } - outOS.flush(); - } - - private void copy(long offset, int length, SeekableSource source, OutputStream output) - throws IOException - { - source.seek(offset); - while (length > 0) { - int len = Math.min(buf.capacity(), length); - buf.clear().limit(len); - int res = source.read(buf); - if (res == -1) - throw new EOFException("in copy " + offset + " " + length); - output.write(buf.array(), 0, res); - length -= res; - } - } - - private void append(int length, InputStream patch, OutputStream output) throws IOException { - while (length > 0) { - int len = Math.min(buf2.length, length); - int res = patch.read(buf2, 0, len); - if (res == -1) - throw new EOFException("cannot read " + length); - output.write(buf2, 0, res); - length -= res; - } - } - - /** - * Simple command line tool to patch a file. - */ - public static void main(String argv[]) { - - if (argv.length != 3) { - System.err.println("usage GDiffPatch source patch output"); - System.err.println("aborting.."); - return; - } - try { - File sourceFile = new File(argv[0]); - File patchFile = new File(argv[1]); - File outputFile = new File(argv[2]); - - if (sourceFile.length() > Integer.MAX_VALUE || - patchFile.length() > Integer.MAX_VALUE) { - System.err.println("source or patch is too large, max length is " + Integer.MAX_VALUE); - System.err.println("aborting.."); - return; - } - GDiffPatcher patcher = new GDiffPatcher(); - patcher.patch(sourceFile, patchFile, outputFile); - - System.out.println("finished patching file"); - - } catch (Exception ioe) { //gls031504a - System.err.println("error while patching: " + ioe); - } - } -} - diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java deleted file mode 100644 index 8f8dfa2db..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/GDiffWriter.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * - * Copyright (c) 2001 Torgeir Veimo - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -/** - * Outputs a diff following the GDIFF file specification available at - * http://www.w3.org/TR/NOTE-gdiff-19970901.html. - */ -public class GDiffWriter implements DiffWriter { - - /** - * Max length of a chunk. - */ - public static final int CHUNK_SIZE = Short.MAX_VALUE; - - public static final byte EOF = 0; - - /** - * Max length for single length data encode. - */ - public static final int DATA_MAX = 246; - - public static final int DATA_USHORT = 247; - public static final int DATA_INT = 248; - public static final int COPY_USHORT_UBYTE = 249; - public static final int COPY_USHORT_USHORT = 250; - public static final int COPY_USHORT_INT = 251; - public static final int COPY_INT_UBYTE = 252; - public static final int COPY_INT_USHORT = 253; - public static final int COPY_INT_INT = 254; - public static final int COPY_LONG_INT = 255; - - private ByteArrayOutputStream buf = new ByteArrayOutputStream(); - - private boolean debug = false; - - private DataOutputStream output = null; - - /** - * Constructs a new GDiffWriter. - */ - public GDiffWriter(DataOutputStream os) throws IOException { - this.output = os; - // write magic string "d1 ff d1 ff 04" - output.writeByte(0xd1); - output.writeByte(0xff); - output.writeByte(0xd1); - output.writeByte(0xff); - output.writeByte(0x04); - } - - /** - * Constructs a new GDiffWriter. - */ - public GDiffWriter(OutputStream output) throws IOException { - this(new DataOutputStream(output)); - } - - @Override - public void addCopy(long offset, int length) throws IOException { - writeBuf(); - - //output debug data - if (debug) - System.err.println("COPY off: " + offset + ", len: " + length); - - // output real data - if (offset > Integer.MAX_VALUE) { - // Actually, we don't support longer files than int.MAX_VALUE at the moment.. - output.writeByte(COPY_LONG_INT); - output.writeLong(offset); - output.writeInt(length); - } else if (offset < 65536) { - if (length < 256) { - output.writeByte(COPY_USHORT_UBYTE); - output.writeShort((int)offset); - output.writeByte(length); - } else if (length > 65535) { - output.writeByte(COPY_USHORT_INT); - output.writeShort((int)offset); - output.writeInt(length); - } else { - output.writeByte(COPY_USHORT_USHORT); - output.writeShort((int)offset); - output.writeShort(length); - } - } else { - if (length < 256) { - output.writeByte(COPY_INT_UBYTE); - output.writeInt((int)offset); - output.writeByte(length); - } else if (length > 65535) { - output.writeByte(COPY_INT_INT); - output.writeInt((int)offset); - output.writeInt(length); - } else { - output.writeByte(COPY_INT_USHORT); - output.writeInt((int)offset); - output.writeShort(length); - } - } - } - - /** - * Adds a data byte. - */ - @Override - public void addData(byte b) throws IOException { - buf.write(b); - if (buf.size() >= CHUNK_SIZE) - writeBuf(); - } - - private void writeBuf() throws IOException { - if (buf.size() > 0) { - if (buf.size() <= DATA_MAX) { - output.writeByte(buf.size()); - } else if (buf.size() <= 65535) { - output.writeByte(DATA_USHORT); - output.writeShort(buf.size()); - } else { - output.writeByte(DATA_INT); - output.writeInt(buf.size()); - } - buf.writeTo(output); - buf.reset(); - } - } - - /** - * Flushes accumulated data bytes, if any. - */ - @Override - public void flush() throws IOException - { - writeBuf(); - output.flush(); - } - - /** - * Writes the final EOF byte, closes the underlying stream. - */ - @Override - public void close() throws IOException { - this.flush(); - output.write(EOF); - output.close(); - } - -} - diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java deleted file mode 100644 index 6eff45119..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/PatchException.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * PatchException.java - * - * Created on June 6, 2006, 9:34 PM - * Copyright (c) 2006 Heiko Klein - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.IOException; - -/** - * Thrown when a patch is invalid. - */ -public class PatchException extends IOException { - - private static final long serialVersionUID = 1; - - /** - * Creates a new instance of PatchException without detail message. - */ - public PatchException() { - } - - /** - * Constructs an instance of PatchException with the specified detail message. - * @param msg the detail message. - */ - public PatchException(String msg) { - super(msg); - } -} diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java deleted file mode 100644 index fad58fc9c..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/RandomAccessFileSeekableSource.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * RandomAccessFileSeekableSource.java - * - * Created on May 17, 2006, 1:45 PM - * Copyright (c) 2006 Heiko Klein - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; - -/** - * Wraps a random access file. - */ -public class RandomAccessFileSeekableSource implements SeekableSource { - - private RandomAccessFile raf; - - /** - * Constructs a new RandomAccessFileSeekableSource. - * @param raf - */ - public RandomAccessFileSeekableSource(RandomAccessFile raf) { - if (raf == null) - throw new NullPointerException("raf"); - this.raf = raf; - } - - @Override - public void seek(long pos) throws IOException { - raf.seek(pos); - } - - public int read(byte[] b, int off, int len) throws IOException { - return raf.read(b, off, len); - } - - public long length() throws IOException { - return raf.length(); - } - - @Override - public void close() throws IOException { - raf.close(); - } - - @Override - public int read(ByteBuffer bb) throws IOException { - int c = raf.read(bb.array(), bb.position(), bb.remaining()); - if (c == -1) - return -1; - bb.position(bb.position() + c); - return c; - } - -} diff --git a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java b/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java deleted file mode 100644 index a309f02a1..000000000 --- a/src/main/java/net/minecraftforge/fml/repackage/com/nothome/delta/SeekableSource.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SeekableSource.java - * - * Created on May 17, 2006, 12:33 PM - * Copyright (c) 2006 Heiko Klein - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - */ - -package net.minecraftforge.fml.repackage.com.nothome.delta; - -import java.io.Closeable; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.ByteBuffer; - -/** - * For sources of random-access data, such as {@link RandomAccessFile}. - */ -public interface SeekableSource extends Closeable { - - /** - * Sets the position for the next {@link #read(ByteBuffer)}. - */ - void seek(long pos) throws IOException ; - - /** - * Reads up to {@link ByteBuffer#remaining()} bytes from the source, - * returning the number of bytes read, or -1 if no bytes were read - * and EOF was reached. - */ - int read(ByteBuffer bb) throws IOException; - -} diff --git a/src/main/java/net/minecraftforge/logging/ModelLoaderErrorMessage.java b/src/main/java/net/minecraftforge/logging/ModelLoaderErrorMessage.java index 4cd6c6de2..7f8e41354 100644 --- a/src/main/java/net/minecraftforge/logging/ModelLoaderErrorMessage.java +++ b/src/main/java/net/minecraftforge/logging/ModelLoaderErrorMessage.java @@ -31,7 +31,8 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.IRegistry; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.registry.ForgeRegistries; +import net.minecraftforge.registries.ForgeRegistries; + import org.apache.logging.log4j.message.SimpleMessage; import java.util.Collection; diff --git a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java similarity index 94% rename from src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java rename to src/main/java/net/minecraftforge/registries/ForgeRegistries.java index a379d5f37..bccbbf604 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/ForgeRegistries.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistries.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.common.registry; +package net.minecraftforge.registries; import net.minecraft.block.Block; import net.minecraft.enchantment.Enchantment; @@ -29,10 +29,9 @@ import net.minecraft.potion.Potion; import net.minecraft.potion.PotionType; import net.minecraft.util.SoundEvent; import net.minecraft.world.biome.Biome; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.fml.common.registry.VillagerRegistry; import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession; -import net.minecraftforge.registries.GameData; -import net.minecraftforge.registries.IForgeRegistry; -import net.minecraftforge.registries.RegistryManager; /** * A class that exposes static references to all vanilla and Forge registries. diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index b49f1ffae..adf15987d 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -198,19 +198,9 @@ public class ForgeRegistry> implements IForgeRe return Collections.unmodifiableSet(this.names.keySet()); } - /** - * @deprecated use {@link #getValuesCollection} to avoid copying - */ - @Deprecated - @Override - public List getValues() - { - return ImmutableList.copyOf(this.names.values()); - } - @Nonnull @Override - public Collection getValuesCollection() + public Collection getValues() { return Collections.unmodifiableSet(this.names.values()); } @@ -793,7 +783,7 @@ public class ForgeRegistry> implements IForgeRe NBTTagCompound tag = new NBTTagCompound(); tag.setString("K", e.getKey().toString()); tag.setInteger("V", e.getValue()); - ids.appendTag(tag); + ids.add(tag); }); data.setTag("ids", ids); @@ -803,7 +793,7 @@ public class ForgeRegistry> implements IForgeRe NBTTagCompound tag = new NBTTagCompound(); tag.setString("K", e.getKey().toString()); tag.setString("V", e.getKey().toString()); - aliases.appendTag(tag); + aliases.add(tag); }); data.setTag("aliases", aliases); @@ -813,7 +803,7 @@ public class ForgeRegistry> implements IForgeRe NBTTagCompound tag = new NBTTagCompound(); tag.setString("K", e.getKey().toString()); tag.setString("V", e.getValue()); - overrides.appendTag(tag); + overrides.add(tag); }); data.setTag("overrides", overrides); @@ -821,7 +811,7 @@ public class ForgeRegistry> implements IForgeRe data.setIntArray("blocked", blocked); NBTTagList dummied = new NBTTagList(); - this.dummied.stream().sorted().forEach(e -> dummied.appendTag(new NBTTagString(e.toString()))); + this.dummied.stream().sorted().forEach(e -> dummied.add(new NBTTagString(e.toString()))); data.setTag("dummied", dummied); return data; @@ -846,24 +836,7 @@ public class ForgeRegistry> implements IForgeRe list.forEach(e -> { NBTTagCompound comp = (NBTTagCompound)e; - String v = comp.getString("V"); - if (v.indexOf(':') == -1) //Forge Bug: https://github.com/MinecraftForge/MinecraftForge/issues/4894 TODO: Remove in 1.13 - { - ret.overrides.put(new ResourceLocation(comp.getString("K")), v); - } - else - { - ResourceLocation aliask = new ResourceLocation(comp.getString("K")); - ResourceLocation aliasv = new ResourceLocation(v); - if (aliasv.equals(aliask)) - { - FMLLog.log.warn("Found unrecoverable 4894 bugged alias/override: {} -> {}, skipping.", aliask, aliasv); - } - else - { - ret.aliases.put(aliask, aliasv); - } - } + ret.overrides.put(new ResourceLocation(comp.getString("K")), comp.getString("V")); }); list = nbt.getTagList("overrides", 10); diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistryEntry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistryEntry.java index dbe99aed0..d0e9f3a3c 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistryEntry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistryEntry.java @@ -30,7 +30,7 @@ import javax.annotation.Nullable; * if another entry overrides existing ones in the registry. */ @SuppressWarnings("unchecked") -public abstract class ForgeRegistryEntry> implements IForgeRegistryEntry +public abstract class ForgeRegistryEntry> implements IForgeRegistryEntry { @SuppressWarnings("serial") private final TypeToken token = new TypeToken(getClass()){}; diff --git a/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java b/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java index 14f4d4f18..550b5db24 100644 --- a/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java +++ b/src/main/java/net/minecraftforge/registries/IForgeRegistryModifiable.java @@ -21,7 +21,7 @@ package net.minecraftforge.registries; import net.minecraft.util.ResourceLocation; -public interface IForgeRegistryModifiable> extends IForgeRegistry +public interface IForgeRegistryModifiable> extends IForgeRegistry { void clear(); V remove(ResourceLocation key); diff --git a/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java b/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java index 497b70c7f..b827d903a 100644 --- a/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java +++ b/src/main/java/net/minecraftforge/registries/NamespacedDefaultedWrapper.java @@ -122,7 +122,7 @@ class NamespacedDefaultedWrapper> extends Regis @Nullable public V getRandomObject(Random random) { - Collection values = this.delegate.getValuesCollection(); + Collection values = this.delegate.getValues(); return values.stream().skip(random.nextInt(values.size())).findFirst().orElse(null); } diff --git a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java index d5746963c..71192abfb 100644 --- a/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java +++ b/src/main/java/net/minecraftforge/registries/NamespacedWrapper.java @@ -117,7 +117,7 @@ class NamespacedWrapper> extends RegistryNamesp @Nullable public V getRandomObject(Random random) { - Collection values = this.delegate.getValuesCollection(); + Collection values = this.delegate.getValues(); return values.stream().skip(random.nextInt(values.size())).findFirst().orElse(null); } diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolder.java b/src/main/java/net/minecraftforge/registries/ObjectHolder.java new file mode 100644 index 000000000..ded07a291 --- /dev/null +++ b/src/main/java/net/minecraftforge/registries/ObjectHolder.java @@ -0,0 +1,42 @@ +/* + * Minecraft Forge + * Copyright (c) 2016-2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package net.minecraftforge.registries; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ObjectHolder can be used to automatically populate public static final fields with entries + * from the registry. These values can then be referred within mod code directly. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) +public @interface ObjectHolder +{ + /** + * If used on a class, this represents a modid only. + * If used on a field, it represents a name, which can be abbreviated or complete. + * Abbreviated names derive their modid from an enclosing ObjectHolder at the class level. + * + * @return either a modid or a name based on the rules above + */ + String value(); +} diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java b/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java index 63fa14e7c..328bcae72 100644 --- a/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java +++ b/src/main/java/net/minecraftforge/registries/ObjectHolderRef.java @@ -20,7 +20,6 @@ package net.minecraftforge.registries; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collections; import java.util.LinkedList; @@ -28,23 +27,23 @@ import java.util.Queue; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; - import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + /** * Internal class used in tracking {@link ObjectHolder} references */ @SuppressWarnings("rawtypes") class ObjectHolderRef { + private static final Logger LOGGER = LogManager.getLogger(); private Field field; private ResourceLocation injectedObject; private boolean isValid; private ForgeRegistry registry; - @SuppressWarnings("unchecked") ObjectHolderRef(Field field, ResourceLocation injectedObject, boolean extractFromExistingValues) { registry = getRegistryForType(field); @@ -66,7 +65,7 @@ class ObjectHolderRef } else { - this.injectedObject = ((ForgeRegistryEntry)existing).getRegistryName(); + this.injectedObject = ((IForgeRegistryEntry)existing).getRegistryName(); } } catch (IllegalAccessException e) @@ -83,13 +82,12 @@ class ObjectHolderRef { throw new IllegalStateException(String.format("The ObjectHolder annotation cannot apply to a field that does not map to a registry. Ensure the registry was created during the RegistryEvent.NewRegistry event. (found : %s at %s.%s)", field.getType().getName(), field.getClass().getName(), field.getName())); } - try + + field.setAccessible(true); + + if (Modifier.isFinal(field.getModifiers())) { - FinalFieldHelper.makeWritable(field); - } - catch (ReflectiveOperationException e) - { - throw new RuntimeException(e); + throw new RuntimeException("@ObjectHolder on final field, our transformer did not run? " + field.getDeclaringClass().getName() + "/" + field.getName()); } } @@ -137,46 +135,16 @@ class ObjectHolderRef if (thing == null) { - FMLLog.log.debug("Unable to lookup {} for {}. This means the object wasn't registered. It's likely just mod options.", injectedObject, field); + LOGGER.debug("Unable to lookup {} for {}. This means the object wasn't registered. It's likely just mod options.", injectedObject, field); return; } try { - FinalFieldHelper.setField(field, null, thing); + field.set(null, thing); } catch (IllegalArgumentException | ReflectiveOperationException e) { - FMLLog.log.warn("Unable to set {} with value {} ({})", this.field, thing, this.injectedObject, e); - } - } - - private static class FinalFieldHelper - { - private static Field modifiersField; - private static Object reflectionFactory; - private static Method newFieldAccessor; - private static Method fieldAccessorSet; - - static Field makeWritable(Field f) throws ReflectiveOperationException - { - f.setAccessible(true); - if (modifiersField == null) - { - Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory"); - reflectionFactory = getReflectionFactory.invoke(null); - newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class); - fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class); - modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - } - modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL); - return f; - } - - static void setField(Field field, @Nullable Object instance, Object thing) throws ReflectiveOperationException - { - Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false); - fieldAccessorSet.invoke(fieldAccessor, instance, thing); + LOGGER.warn("Unable to set {} with value {} ({})", this.field, thing, this.injectedObject, e); } } } diff --git a/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java b/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java index 3104e993d..4fff52f5f 100644 --- a/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ObjectHolderRegistry.java @@ -26,66 +26,48 @@ import java.util.Map; import java.util.Set; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import javax.annotation.Nullable; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.Opcodes; + /** * Internal registry for tracking {@link ObjectHolder} references */ public enum ObjectHolderRegistry { INSTANCE; + private static final Logger LOGGER = LogManager.getLogger(); private List objectHolders = Lists.newArrayList(); public void findObjectHolders(ASMDataTable table) { - FMLLog.log.info("Processing ObjectHolder annotations"); - Set allObjectHolders = table.getAll(GameRegistry.ObjectHolder.class.getName()); + LOGGER.info("Processing ObjectHolder annotations"); + Set allObjectHolders = table.getAll(ObjectHolder.class.getName()); Map classModIds = Maps.newHashMap(); Map> classCache = Maps.newHashMap(); - for (ASMData data : table.getAll(Mod.class.getName())) - { - String modid = (String)data.getAnnotationInfo().get("modid"); - classModIds.put(data.getClassName(), modid); - } - for (ASMData data : allObjectHolders) - { - String className = data.getClassName(); - String annotationTarget = data.getObjectName(); - String value = (String) data.getAnnotationInfo().get("value"); - boolean isClass = className.equals(annotationTarget); - if (isClass) - { - scanTarget(classModIds, classCache, className, annotationTarget, value, isClass, false); - } - } + + table.getAll(Mod.class.getName()).forEach(data -> classModIds.put(data.getClassName(), (String)data.getAnnotationInfo().get("value"))); + // double pass - get all the class level annotations first, then the field level annotations - for (ASMData data : allObjectHolders) + allObjectHolders.stream().filter(data -> data.getObjectName().equals(data.getClassName())).forEach(data -> { - String className = data.getClassName(); - String annotationTarget = data.getObjectName(); - String value = (String) data.getAnnotationInfo().get("value"); - boolean isClass = className.equals(annotationTarget); - if (!isClass) - { - scanTarget(classModIds, classCache, className, annotationTarget, value, isClass, false); - } - } - scanTarget(classModIds, classCache, "net.minecraft.init.Blocks", null, "minecraft", true, true); - scanTarget(classModIds, classCache, "net.minecraft.init.Items", null, "minecraft", true, true); - scanTarget(classModIds, classCache, "net.minecraft.init.MobEffects", null, "minecraft", true, true); - scanTarget(classModIds, classCache, "net.minecraft.init.Biomes", null, "minecraft", true, true); - scanTarget(classModIds, classCache, "net.minecraft.init.Enchantments", null, "minecraft", true, true); - scanTarget(classModIds, classCache, "net.minecraft.init.SoundEvents", null, "minecraft", true, true); - scanTarget(classModIds, classCache, "net.minecraft.init.PotionTypes", null, "minecraft", true, true); - FMLLog.log.info("Found {} ObjectHolder annotations", objectHolders.size()); + String value = (String)data.getAnnotationInfo().get("value"); + scanTarget(classModIds, classCache, data.getClassName(), data.getObjectName(), value, true, data.getClassName().startsWith("net.minecraft.init")); + }); + allObjectHolders.stream().filter(data -> !data.getObjectName().equals(data.getClassName())).forEach(data -> + { + String value = (String)data.getAnnotationInfo().get("value"); + scanTarget(classModIds, classCache, data.getClassName(), data.getObjectName(), value, false, false); + }); + LOGGER.info("Found {} ObjectHolder annotations", objectHolders.size()); } private void scanTarget(Map classModIds, Map> classCache, String className, @Nullable String annotationTarget, String value, boolean isClass, boolean extractFromValue) @@ -119,7 +101,7 @@ public enum ObjectHolderRegistry String prefix = classModIds.get(className); if (prefix == null) { - FMLLog.log.warn("Found an unqualified ObjectHolder annotation ({}) without a modid context at {}.{}, ignoring", value, className, annotationTarget); + LOGGER.warn("Found an unqualified ObjectHolder annotation ({}) without a modid context at {}.{}, ignoring", value, className, annotationTarget); throw new IllegalStateException("Unqualified reference to ObjectHolder"); } value = prefix + ":" + value; @@ -140,11 +122,10 @@ public enum ObjectHolderRegistry private void scanClassForFields(Map classModIds, String className, String value, Class clazz, boolean extractFromExistingValues) { classModIds.put(className, value); + final int flags = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC; for (Field f : clazz.getFields()) { - int mods = f.getModifiers(); - boolean isMatch = Modifier.isPublic(mods) && Modifier.isStatic(mods) && Modifier.isFinal(mods); - if (!isMatch || f.isAnnotationPresent(ObjectHolder.class)) + if (((f.getModifiers() & flags) != flags) || f.isAnnotationPresent(ObjectHolder.class)) { continue; } @@ -162,12 +143,9 @@ public enum ObjectHolderRegistry public void applyObjectHolders() { - FMLLog.log.info("Applying holder lookups"); - for (ObjectHolderRef ohr : objectHolders) - { - ohr.apply(); - } - FMLLog.log.info("Holder lookups applied"); + LOGGER.info("Applying holder lookups"); + objectHolders.forEach(ObjectHolderRef::apply); + LOGGER.info("Holder lookups applied"); } } diff --git a/src/main/java/paulscode/sound/codecs/CodecIBXM.java b/src/main/java/paulscode/sound/codecs/CodecIBXM.java deleted file mode 100644 index f3e9e4bf5..000000000 --- a/src/main/java/paulscode/sound/codecs/CodecIBXM.java +++ /dev/null @@ -1,652 +0,0 @@ -package paulscode.sound.codecs; - -import java.io.DataInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.net.URL; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.ShortBuffer; - -import javax.sound.sampled.AudioFormat; - -import paulscode.sound.ICodec; -import paulscode.sound.SoundBuffer; -import paulscode.sound.SoundSystemConfig; -import paulscode.sound.SoundSystemLogger; -import ibxm.FastTracker2; -import ibxm.IBXM; -import ibxm.Module; -import ibxm.ProTracker; -import ibxm.ScreamTracker3; - -/** - * The CodecIBXM class provides an ICodec interface for reading from MOD/S3M/XM - * files via the IBXM library. - * SoundSystem CodecIBXM Class License:

- * 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 - * like, provided the following conditions are met: - *
- * 1) You may not falsely claim to be the author of this class or any - * unmodified portion of it. - *
- * 2) You may not copyright this class or a modified version of it and then - * sue me for copyright infringement. - *
- * 3) If you modify the source code, you must clearly document the changes - * made before redistributing the modified source code, so other users know - * it is not the original code. - *
- * 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: - * http://www.paulscode.com - *
- * 5) I the author will not be responsible for any damages (physical, - * financial, or otherwise) caused by the use if this class or any portion - * of it. - *
- * 6) I the author do not guarantee, warrant, or make any representations, - * either expressed or implied, regarding the use of this class or any - * portion of it. - *

- * Author: Paul Lamb - *
- * http://www.paulscode.com - *


- * - * This software is based on or using the IBXM library available from - * http://www.geocities.com/sunet2000/ - *

- *
- * IBXM is copyright (c) 2007, Martin Cameron, and is licensed under the BSD - * License. - *

- * All rights reserved. - *

- * 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 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. - *

- * 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. - *


- */ -public class CodecIBXM implements ICodec -{ -/** - * Used to return a current value from one of the synchronized - * boolean-interface methods. - */ - private static final boolean GET = false; - -/** - * Used to set the value in one of the synchronized boolean-interface methods. - */ - private static final boolean SET = true; - -/** - * Used when a parameter for one of the synchronized boolean-interface methods - * is not aplicable. - */ - private static final boolean XXX = false; - -/** - * True if there is no more data to read in. - */ - private boolean endOfStream = false; - -/** - * True if the stream has finished initializing. - */ - private boolean initialized = false; - -/** - * Format the converted audio will be in. - */ - private AudioFormat myAudioFormat = null; - -/** - * True if the using library requires data read by this codec to be - * reverse-ordered before returning it from methods read() and readAll(). - */ - private boolean reverseBytes = false; - -/** - * IBXM decoder. - */ - private IBXM ibxm; - -/** - * Module instance to be played. - */ - private Module module; - -/** - * Duration of the audio (in frames). - */ - private int songDuration; - -/** - * Audio read position (in frames). - */ - private int playPosition; - -/** - * Processes status messages, warnings, and error messages. - */ - private SoundSystemLogger logger; - -/** - * Constructor: Grabs a handle to the logger. - */ - public CodecIBXM() - { - logger = SoundSystemConfig.getLogger(); - } - -/** - * Tells this codec when it will need to reverse the byte order of - * the data before returning it in the read() and readAll() methods. The - * IBXM library produces audio data in a format that some external audio - * libraries require to be reversed. Derivatives of the Library and Source - * classes for audio libraries which require this type of data to be reversed - * will call the reverseByteOrder() method. - * @param b True if the calling audio library requires byte-reversal. - */ - @Override - public void reverseByteOrder( boolean b ) - { - reverseBytes = b; - } - -/** - * Prepares an audio stream to read from. If another stream is already opened, - * it will be closed and a new audio stream opened in its place. - * @param url URL to an audio file to stream from. - * @return False if an error occurred or if end of stream was reached. - */ - @Override - public boolean initialize( URL url ) - { - initialized( SET, false ); - cleanup(); - - if( url == null ) - { - errorMessage( "url null in method 'initialize'" ); - cleanup(); - return false; - } - - InputStream is = null; - - try - { - is = url.openStream(); - } - catch( IOException ioe ) - { - errorMessage( "Unable to open stream in method 'initialize'" ); - printStackTrace( ioe ); - return false; - } - - if( ibxm == null ) - ibxm = new IBXM( 48000 ); - if( myAudioFormat == null ) - myAudioFormat = new AudioFormat( 48000, 16, 2, true, true ); - - try - { - setModule( loadModule( is ) ); - } - catch( IllegalArgumentException iae ) - { - errorMessage( "Illegal argument in method 'initialize'" ); - printStackTrace( iae ); - if( is != null ) - { - try - { - is.close(); - } - catch( IOException ioe ) - {} - } - return false; - } - catch( IOException ioe ) - { - errorMessage( "Error loading module in method 'initialize'" ); - printStackTrace( ioe ); - if( is != null ) - { - try - { - is.close(); - } - catch( IOException ioe2 ) - {} - } - return false; - } - - if( is != null ) - { - try - { - is.close(); - } - catch( IOException ioe ) - {} - } - - endOfStream( SET, false ); - initialized( SET, true ); - return true; - } - -/** - * Returns false if the stream is busy initializing. - * @return True if steam is initialized. - */ - @Override - public boolean initialized() - { - return initialized( GET, XXX ); - } - -/** - * Reads in one stream buffer worth of audio data. See - * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more - * information about accessing and changing default settings. - * @return The audio data wrapped into a SoundBuffer context. - */ - @Override - public SoundBuffer read() - { - if( endOfStream( GET, XXX ) ) - return null; - - if( module == null ) - { - errorMessage( "Module null in method 'read'" ); - return null; - } - - // Check to make sure there is an audio format: - if( myAudioFormat == null ) - { - errorMessage( "Audio Format null in method 'read'" ); - return null; - } - - int bufferFrameSize = (int) SoundSystemConfig.getStreamingBufferSize() - / 4; - - int frames = songDuration - playPosition; - if( frames > bufferFrameSize ) - frames = bufferFrameSize; - - if( frames <= 0 ) - { - endOfStream( SET, true ); - return null; - } - byte[] outputBuffer = new byte[ frames * 4 ]; - - ibxm.get_audio( outputBuffer, frames ); - - playPosition += frames; - if( playPosition >= songDuration ) - { - endOfStream( SET, true ); - } - - // Reverse the byte order if necessary: - if( reverseBytes ) - reverseBytes( outputBuffer, 0, frames * 4 ); - - // Wrap the data into a SoundBuffer: - SoundBuffer buffer = new SoundBuffer( outputBuffer, myAudioFormat ); - - return buffer; - } - -/** - * Reads in all the audio data from the stream (up to the default - * "maximum file size". See - * {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more - * information about accessing and changing default settings. - * @return the audio data wrapped into a SoundBuffer context. - */ - @Override - public SoundBuffer readAll() - { - if( module == null ) - { - errorMessage( "Module null in method 'readAll'" ); - return null; - } - - // Check to make sure there is an audio format: - if( myAudioFormat == null ) - { - errorMessage( "Audio Format null in method 'readAll'" ); - return null; - } - - int bufferFrameSize = (int) SoundSystemConfig.getFileChunkSize() - / 4; - - byte[] outputBuffer = new byte[ bufferFrameSize * 4 ]; - - // Buffer to contain the audio data: - byte[] fullBuffer = null; - // frames of audio data: - int frames; - // bytes of audio data: - int totalBytes = 0; - - while( (!endOfStream(GET, XXX)) && - (totalBytes < SoundSystemConfig.getMaxFileSize()) ) - { - frames = songDuration - playPosition; - if( frames > bufferFrameSize ) - frames = bufferFrameSize; - ibxm.get_audio( outputBuffer, frames ); - totalBytes += (frames * 4); - - fullBuffer = appendByteArrays( fullBuffer, outputBuffer, - frames * 4 ); - - playPosition += frames; - if( playPosition >= songDuration ) - { - endOfStream( SET, true ); - } - } - - // Reverse the byte order if necessary: - if( reverseBytes ) - reverseBytes( fullBuffer, 0, totalBytes ); - - // Wrap the data into a SoundBuffer: - SoundBuffer buffer = new SoundBuffer( fullBuffer, myAudioFormat ); - - return buffer; - } - -/** - * Returns false if there is still more data available to be read in. - * @return True if end of stream was reached. - */ - @Override - public boolean endOfStream() - { - return endOfStream( GET, XXX ); - } - -/** - * Closes the audio stream and remove references to all instantiated objects. - */ - @Override - public void cleanup() - { -// if( ibxm != null ) -// ibxm.seek( 0 ); - playPosition = 0; - } - -/** - * Returns the audio format of the data being returned by the read() and - * readAll() methods. - * @return Information wrapped into an AudioFormat context. - */ - @Override - public AudioFormat getAudioFormat() - { - return myAudioFormat; - } - -/** - * Decodes the data in the specified InputStream into an instance of - * ibxm.Module. - * @param input an InputStream containing the module file to be decoded. - * @throws IllegalArgumentException if the data is not recognised as a module file. - */ - private static Module loadModule( InputStream input ) - throws IllegalArgumentException, IOException - { - DataInputStream data_input_stream = new DataInputStream( input ); - - // Check if data is in XM format: - byte[] xm_header = new byte[ 60 ]; - data_input_stream.readFully( xm_header ); - if( FastTracker2.is_xm( xm_header ) ) - return FastTracker2.load_xm( xm_header, data_input_stream ); - - // Check if data is in ScreamTracker 3 format: - byte[] s3m_header = new byte[ 96 ]; - System.arraycopy( xm_header, 0, s3m_header, 0, 60 ); - data_input_stream.readFully( s3m_header, 60, 36 ); - if( ScreamTracker3.is_s3m( s3m_header ) ) - return ScreamTracker3.load_s3m( s3m_header, data_input_stream ); - - // Check if data is in ProTracker format: - byte[] mod_header = new byte[ 1084 ]; - System.arraycopy( s3m_header, 0, mod_header, 0, 96 ); - data_input_stream.readFully( mod_header, 96, 988 ); - return ProTracker.load_mod( mod_header, data_input_stream ); - } - -/** - * Sets the Module instance to be played. - */ - private void setModule( Module m ) - { - if( m != null ) - module = m; - ibxm.set_module( module ); - songDuration = ibxm.calculate_song_duration(); - } - -/** - * Internal method for synchronizing access to the boolean 'initialized'. - * @param action GET or SET. - * @param value New value if action == SET, or XXX if action == GET. - * @return True if steam is initialized. - */ - private synchronized boolean initialized( boolean action, boolean value ) - { - if( action == SET ) - initialized = value; - return initialized; - } - -/** - * Internal method for synchronizing access to the boolean 'endOfStream'. - * @param action GET or SET. - * @param value New value if action == SET, or XXX if action == GET. - * @return True if end of stream was reached. - */ - private synchronized boolean endOfStream( boolean action, boolean value ) - { - if( action == SET ) - endOfStream = value; - return endOfStream; - } - -/** - * Trims down the size of the array if it is larger than the specified - * maximum length. - * @param array Array containing audio data. - * @param maxLength Maximum size this array may be. - * @return New array. - */ - @SuppressWarnings("unused") //Forge - private static byte[] trimArray( byte[] array, int maxLength ) - { - byte[] trimmedArray = null; - if( array != null && array.length > maxLength ) - { - trimmedArray = new byte[maxLength]; - System.arraycopy( array, 0, trimmedArray, 0, maxLength ); - } - return trimmedArray; - } - -/** - * Reverse-orders all bytes contained in the specified array. - * @param buffer Array containing audio data. - */ - public static void reverseBytes( byte[] buffer ) - { - reverseBytes( buffer, 0, buffer.length ); - } - -/** - * Reverse-orders the specified range of bytes contained in the specified array. - * @param buffer Array containing audio data. - * @param offset Array index to begin. - * @param size number of bytes to reverse-order. - */ - public static void reverseBytes( byte[] buffer, int offset, int size ) - { - - byte b; - for( int i = offset; i < ( offset + size ); i += 2 ) - { - b = buffer[i]; - buffer[i] = buffer[i + 1]; - buffer[i + 1] = b; - } - } - -/** - * Converts sound bytes to little-endian format. - * @param audio_bytes The original wave data - * @param two_bytes_data For stereo sounds. - * @return byte array containing the converted data. - */ - @SuppressWarnings("unused") //Forge - private static byte[] convertAudioBytes( byte[] audio_bytes, - boolean two_bytes_data ) - { - ByteBuffer dest = ByteBuffer.allocateDirect( audio_bytes.length ); - dest.order( ByteOrder.nativeOrder() ); - ByteBuffer src = ByteBuffer.wrap( audio_bytes ); - src.order( ByteOrder.LITTLE_ENDIAN ); - if( two_bytes_data ) - { - ShortBuffer dest_short = dest.asShortBuffer(); - ShortBuffer src_short = src.asShortBuffer(); - while( src_short.hasRemaining() ) - { - dest_short.put(src_short.get()); - } - } - else - { - while( src.hasRemaining() ) - { - dest.put( src.get() ); - } - } - dest.rewind(); - - if( !dest.hasArray() ) - { - byte[] arrayBackedBuffer = new byte[dest.capacity()]; - dest.get( arrayBackedBuffer ); - dest.clear(); - - return arrayBackedBuffer; - } - - return dest.array(); - } - -/** - * Creates a new array with the second array appended to the end of the first - * array. - * @param arrayOne The first array. - * @param arrayTwo The second array. - * @param length How many bytes to append from the second array. - * @return Byte array containing information from both arrays. - */ - private static byte[] appendByteArrays( byte[] arrayOne, byte[] arrayTwo, - int length ) - { - byte[] newArray; - if( arrayOne == null && arrayTwo == null ) - { - // no data, just return - return null; - } - else if( arrayOne == null ) - { - // create the new array, same length as arrayTwo: - newArray = new byte[ length ]; - // fill the new array with the contents of arrayTwo: - System.arraycopy( arrayTwo, 0, newArray, 0, length ); - arrayTwo = null; - } - else if( arrayTwo == null ) - { - // create the new array, same length as arrayOne: - newArray = new byte[ arrayOne.length ]; - // fill the new array with the contents of arrayOne: - System.arraycopy( arrayOne, 0, newArray, 0, arrayOne.length ); - arrayOne = null; - } - else - { - // create the new array large enough to hold both arrays: - newArray = new byte[ arrayOne.length + length ]; - System.arraycopy( arrayOne, 0, newArray, 0, arrayOne.length ); - // fill the new array with the contents of both arrays: - System.arraycopy( arrayTwo, 0, newArray, arrayOne.length, - length ); - arrayOne = null; - arrayTwo = null; - } - - return newArray; - } - -/** - * Prints an error message. - * @param message Message to print. - */ - private void errorMessage( String message ) - { - logger.errorMessage( "CodecWav", message, 0 ); - } - -/** - * Prints an exception's error message followed by the stack trace. - * @param e Exception containing the information to print. - */ - private void printStackTrace( Exception e ) - { - logger.printStackTrace( e, 1 ); - } -} diff --git a/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService b/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService index cdcf67fe4..e8e16bd67 100644 --- a/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService +++ b/src/main/resources/META-INF/services/cpw.mods.modlauncher.serviceapi.ILaunchPluginService @@ -1 +1,3 @@ -net.minecraftforge.fml.loading.RuntimeDistCleaner \ No newline at end of file +net.minecraftforge.fml.loading.RuntimeDistCleaner +net.minecraftforge.common.asm.RuntimeEnumExtener +net.minecraftforge.common.asm.ObjectHolderDefinalize diff --git a/src/main/resources/forge.exc b/src/main/resources/forge.exc index ff2c10d2e..43fcdb921 100644 --- a/src/main/resources/forge.exc +++ b/src/main/resources/forge.exc @@ -80,3 +80,5 @@ net/minecraft/command/EntitySelector.isSelectorDefault(Ljava/lang/String;)Z=|p_8 net/minecraft/client/util/RecipeItemHelper.accountStack(Lnet/minecraft/item/ItemStack;I)V=|p_194112_1_,forceCount net/minecraft/client/renderer/ActiveRenderInfo.updateRenderInfo(Lnet/minecraft/entity/Entity;Z)V=|p_74583_0_,p_74583_1_ net/minecraft/client/audio/SoundManager.setListener(Lnet/minecraft/entity/Entity;F)V=|p_148615_1_,p_148615_2_ + +net/minecraft/item/ArmorMaterial.create(Ljava/lang/String;Ljava/lang/String;I[IILnet/minecraft/util/SoundEvent;FLjava/util/function/Supplier;)V=|name,p_i48533_3_,p_i48533_4_,p_i48533_5_,p_i48533_6_,p_i48533_7_,p_i48533_8_,p_i48533_9_