diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index 8188e150752..a9c5adbce94 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -123,6 +123,21 @@ 7.6.3 + + com.googlecode.soundlibs + mp3spi + 1.9.5-1 + + + javazoom + jlayer + 1.0.1 + + + org.mobicents.external.tritonus + tritonus_share + 0.3.6 + diff --git a/Mage.Client/src/main/java/mage/client/MageFrame.java b/Mage.Client/src/main/java/mage/client/MageFrame.java index 7ae3188d80d..55569236281 100644 --- a/Mage.Client/src/main/java/mage/client/MageFrame.java +++ b/Mage.Client/src/main/java/mage/client/MageFrame.java @@ -66,6 +66,7 @@ import mage.client.tournament.TournamentPanel; import mage.client.util.EDTExceptionHandler; import mage.client.util.SettingsManager; import mage.client.util.gui.ArrowBuilder; +import mage.client.util.MusicPlayer; import mage.components.ImagePanel; import mage.interfaces.Action; import mage.interfaces.MageClient; @@ -540,10 +541,14 @@ public class MageFrame extends javax.swing.JFrame implements MageClient { ArrowBuilder.getBuilder().hideAllPanels(); if (frame instanceof GamePane) { ArrowBuilder.getBuilder().showPanel(((GamePane) frame).getGameId()); + MusicPlayer.playBGM(); + }else{ + MusicPlayer.stopBGM(); } } public static void deactivate(MagePane frame) { + //MusicPlayer.stopBGM(); frame.setVisible(false); MagePane topmost = getTopMost(frame); if (activeFrame != frame) { diff --git a/Mage.Client/src/main/java/mage/client/constants/Constants.java b/Mage.Client/src/main/java/mage/client/constants/Constants.java index 007cb7cebab..4f5a48a0b62 100644 --- a/Mage.Client/src/main/java/mage/client/constants/Constants.java +++ b/Mage.Client/src/main/java/mage/client/constants/Constants.java @@ -80,7 +80,8 @@ public final class Constants { public static final String RESOURCE_PATH_SET = IO.imageBaseDir + "sets" + File.separator; public static final String RESOURCE_PATH_SET_SMALL = RESOURCE_PATH_SET + File.separator + "small" + File.separator; public static final String BASE_SOUND_PATH = "plugins" + File.separator + "sounds" + File.separator; - + public static final String BASE_MUSICS_PATH = "plugins" + File.separator + "sounds" + File.separator + "musics" + File.separator ; + public interface IO { String imageBaseDir = "plugins" + File.separator + "images" + File.separator; String IMAGE_PROPERTIES_FILE = "image.url.properties"; diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form index c5c0791b453..8b31b07b896 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.form @@ -1,4 +1,4 @@ - +
@@ -7,6 +7,7 @@ + @@ -25,7 +26,7 @@ - + @@ -81,7 +82,7 @@ - + @@ -443,7 +444,7 @@ - + @@ -562,7 +563,10 @@ - + + + + @@ -572,7 +576,9 @@ - + + + @@ -586,6 +592,14 @@ + + + + + + + + diff --git a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java index c1924aaa908..a42facf23c1 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PreferencesDialog.java @@ -73,6 +73,7 @@ public class PreferencesDialog extends javax.swing.JDialog { public static final String KEY_CARD_IMAGES_SAVE_TO_ZIP = "cardImagesSaveToZip"; public static final String KEY_SOUNDS_ON = "soundsOn"; + public static final String KEY_MUSICS_ON = "MusicsOn"; public static final String KEY_BIG_CARD_TOGGLED = "bigCardToggled"; @@ -201,6 +202,7 @@ public class PreferencesDialog extends javax.swing.JDialog { saveToZipFiles = new javax.swing.JCheckBox(); jPanel22 = new javax.swing.JPanel(); jEnableSounds = new javax.swing.JCheckBox(); + jEnableMusics = new javax.swing.JCheckBox(); jPanel6 = new javax.swing.JPanel(); lblProxyType = new javax.swing.JLabel(); cbProxyType = new javax.swing.JComboBox(); @@ -322,7 +324,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(84, Short.MAX_VALUE)) + .addContainerGap(92, Short.MAX_VALUE)) ); jTabbedPane1.addTab("Main", jPanel1); @@ -537,7 +539,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .addGroup(jPanel4Layout.createSequentialGroup() .addContainerGap() .addComponent(jPanel5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(92, Short.MAX_VALUE)) + .addContainerGap(96, Short.MAX_VALUE)) ); jTabbedPane1.addTab("Images", jPanel4); @@ -549,13 +551,22 @@ public class PreferencesDialog extends javax.swing.JDialog { } }); + jEnableMusics.setText("enable BGM"); + jEnableMusics.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jEnableMusicsActionPerformed(evt); + } + }); + javax.swing.GroupLayout jPanel22Layout = new javax.swing.GroupLayout(jPanel22); jPanel22.setLayout(jPanel22Layout); jPanel22Layout.setHorizontalGroup( jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel22Layout.createSequentialGroup() .addGap(19, 19, 19) - .addComponent(jEnableSounds) + .addGroup(jPanel22Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jEnableSounds) + .addComponent(jEnableMusics)) .addContainerGap(325, Short.MAX_VALUE)) ); jPanel22Layout.setVerticalGroup( @@ -563,7 +574,9 @@ public class PreferencesDialog extends javax.swing.JDialog { .addGroup(jPanel22Layout.createSequentialGroup() .addGap(24, 24, 24) .addComponent(jEnableSounds) - .addContainerGap(217, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jEnableMusics) + .addContainerGap(194, Short.MAX_VALUE)) ); jTabbedPane1.addTab("Sounds", jPanel22); @@ -605,7 +618,7 @@ public class PreferencesDialog extends javax.swing.JDialog { } }); - jLabel11.setFont(new java.awt.Font("Tahoma", 2, 10)); + jLabel11.setFont(new java.awt.Font("Tahoma", 2, 10)); // NOI18N jLabel11.setText("Note: password won't be encrypted!"); javax.swing.GroupLayout pnlProxyLayout = new javax.swing.GroupLayout(pnlProxy); @@ -747,7 +760,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .addGap(0, 100, Short.MAX_VALUE) ); - jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel12.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel12.setText("Choose your avatar:"); jPanel12.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true)); @@ -789,7 +802,7 @@ public class PreferencesDialog extends javax.swing.JDialog { .addGap(0, 100, Short.MAX_VALUE) ); - jLabel13.setFont(new java.awt.Font("Tahoma", 1, 11)); + jLabel13.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel13.setText("New avatars:"); jPanel16.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(204, 204, 204), 1, true)); @@ -975,7 +988,7 @@ public class PreferencesDialog extends javax.swing.JDialog { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jTabbedPane1) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(316, Short.MAX_VALUE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(saveButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(exitButton, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE) @@ -1028,7 +1041,7 @@ public class PreferencesDialog extends javax.swing.JDialog { // sounds save(prefs, dialog.jEnableSounds, KEY_SOUNDS_ON, "true", "false", UPDATE_CACHE_POLICY); - + save(prefs, dialog.jEnableMusics, KEY_MUSICS_ON, "true", "false", UPDATE_CACHE_POLICY); // connection save(prefs, dialog.cbProxyType, KEY_PROXY_TYPE); save(prefs, dialog.txtProxyServer, KEY_PROXY_ADDRESS); @@ -1124,6 +1137,10 @@ public class PreferencesDialog extends javax.swing.JDialog { // TODO add your handling code here: }//GEN-LAST:event_jEnableSoundsActionPerformed + private void jEnableMusicsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jEnableMusicsActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jEnableMusicsActionPerformed + private void showProxySettings() { if (cbProxyType.getSelectedItem() == Connection.ProxyType.SOCKS) { this.pnlProxy.setVisible(true); @@ -1231,6 +1248,12 @@ public class PreferencesDialog extends javax.swing.JDialog { } else { dialog.jEnableSounds.setSelected(false); } + prop = prefs.get(KEY_MUSICS_ON, "true"); + if (prop.equals("true")) { + dialog.jEnableMusics.setSelected(true); + } else { + dialog.jEnableMusics.setSelected(false); + } } private static void loadProxySettings(Preferences prefs) { @@ -1449,6 +1472,7 @@ public class PreferencesDialog extends javax.swing.JDialog { private javax.swing.JCheckBox displayBigCardsInHand; private javax.swing.JButton exitButton; private javax.swing.JTextField imageFolderPath; + private javax.swing.JCheckBox jEnableMusics; private javax.swing.JCheckBox jEnableSounds; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel10; diff --git a/Mage.Client/src/main/java/mage/client/util/MusicPlayer.java b/Mage.Client/src/main/java/mage/client/util/MusicPlayer.java new file mode 100644 index 00000000000..9c93f1a3d28 --- /dev/null +++ b/Mage.Client/src/main/java/mage/client/util/MusicPlayer.java @@ -0,0 +1,152 @@ +package mage.client.util; +import java.io.File; +import java.awt.List; +import javax.sound.sampled.*; +import mage.client.constants.Constants; +import mage.client.dialog.PreferencesDialog; +import org.apache.log4j.Logger; + +/** + * + * @author renli + */ + +public class MusicPlayer { + private static final Logger log = Logger.getLogger(AudioManager.class); + String filepath; + String filename; + List filelist = new List(); + static MusicPlayer player = null; + + + //open file and add list + private boolean open(){ + filepath = Constants.BASE_MUSICS_PATH; + filelist.removeAll(); + File filedir = new File(filepath); + File[] fileread = filedir.listFiles(); + if(fileread.length == 0)return false; + String filename; + for(File f:fileread){ + filename = f.getName().toLowerCase(); + if(filename.endsWith(".mp3") || filename.endsWith(".wav")){ + filelist.add(filename); + } + } + if(filelist.getItemCount() == 0) return false; + return true; + } + + public static void playBGM(){ + stopBGM(); + if(player == null){ + player = new MusicPlayer(); + } + if(player.open()){ + player.play(); + } + } + + public void play(){ + String soundsOn = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_MUSICS_ON, "true"); + if(soundsOn.equals("true")){ + player.breaked = false; + player.breaked_out = false; + player.stopped = false; + Thread player = new Thread(new playerThread()); + player.start(); + } + } + + public static void stopBGM(){ + if(player != null){ + player.stopped = true; + player.breaked_out = true; + player.breaked = true; + try { + Thread.sleep(100); + } catch (Exception e) { + log.error("Thread error: " + e); + } + } + } + + public volatile boolean breaked = false; + public volatile boolean breaked_out = false; + public volatile boolean stopped = false; + public volatile FloatControl volume; + AudioInputStream audioInputStream; + AudioFormat audioFormat; + SourceDataLine sourceDataLine; + + + class playerThread extends Thread{ + private void load(File file){ + try{ + audioInputStream = AudioSystem.getAudioInputStream(file); + audioFormat = audioInputStream.getFormat(); + // mp3 decode + if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) { + audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, + audioFormat.getSampleRate(), 16, audioFormat.getChannels(), audioFormat.getChannels() * 2, + audioFormat.getSampleRate(), false); + audioInputStream = AudioSystem.getAudioInputStream(audioFormat, audioInputStream); + } + //output + DataLine.Info dataLineInfo = new DataLine.Info( + SourceDataLine.class, audioFormat, + AudioSystem.NOT_SPECIFIED); + sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); + sourceDataLine.open(audioFormat); + volume = (FloatControl)sourceDataLine.getControl(FloatControl.Type.MASTER_GAIN); + sourceDataLine.start(); + }catch(Exception e){ + log.error("Couldn't load file: " + file + " " + e); + } + + } + + public void run(){ + try { + Thread.sleep(100); + } catch (Exception e) { + } + while(!stopped){ + int it = (int)Math.abs(Math.random()*(filelist.getItemCount())); + File file = new File(filepath + filelist.getItem(it)); + load(file); + Thread PlayThread = new Thread(new PlayThread()); + PlayThread.start(); + while (!(breaked || breaked_out)) { + try { + Thread.sleep(10); + } catch (Exception e) { + log.error("Thread error: " + e); + } + } + breaked = false; + } + } + }; + + class PlayThread extends Thread{ + byte tempBuffer[] = new byte[320]; + public void run(){ + try{ + int len; + while ((len = audioInputStream.read(tempBuffer, 0, + tempBuffer.length)) != -1){ + if(breaked_out) break; + if(len > 0) sourceDataLine.write(tempBuffer, 0, len); + } + //breaked or stopped + sourceDataLine.flush(); + sourceDataLine.close(); + breaked = true; + }catch(Exception e){ + log.error("Thread error: " + e); + } + } + }; +} + diff --git a/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java index 4087bb5f05a..3fecc7dee55 100644 --- a/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java +++ b/Mage.Plugins/Mage.Theme.Plugin/src/main/java/org/mage/plugins/theme/ThemePluginImpl.java @@ -12,6 +12,7 @@ import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; +import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Map; @@ -22,7 +23,9 @@ public class ThemePluginImpl implements ThemePlugin { private static final Logger log = Logger.getLogger(ThemePluginImpl.class); private static BufferedImage background; - + private List flist = new List(); + private String BackgroundDir = "plugins" + File.separator + "plugin.data" + File.separator + + "background" + File.separator; @Init public void init() { } @@ -36,17 +39,37 @@ public class ThemePluginImpl implements ThemePlugin { return "[Theme plugin, version 0.5]"; } - public void applyInGame(Map ui) { - String filename = "/dragon.png"; - try { - InputStream is = this.getClass().getResourceAsStream(filename); - - if (is == null) { - throw new FileNotFoundException("Couldn't find " + filename + " in resources."); + public boolean loadimages(){ + File filedir = new File(BackgroundDir); + File[] filelist = filedir.listFiles(); + if(filelist == null) return false; + if(filelist.length == 0) return false; + for(File f:filelist){ + String filename = f.getName().toLowerCase(); + if(filename != null && (filename.endsWith(".png") || filename.endsWith(".jpg") + || filename.endsWith(".bmp"))){ + flist.add(filename); } - - BufferedImage background = ImageIO.read(is); - + } + if(flist.getItemCount() == 0) return false; + return true; + } + public void applyInGame(Map ui) { + String filename; + BufferedImage background; + try { + if(loadimages()){ + int it = (int)Math.abs(Math.random()*(flist.getItemCount())); + filename = BackgroundDir + flist.getItem(it); + background = ImageIO.read(new File(filename)); + }else{ + filename = "/dragon.png"; + InputStream is = this.getClass().getResourceAsStream(filename); + if (is == null) + throw new FileNotFoundException("Couldn't find " + filename + " in resources."); + background = ImageIO.read(is); + } + if (background == null) { throw new FileNotFoundException("Couldn't find " + filename + " in resources."); }