From 62085ad166ee1da58b433806f85c48e79b0af3ee Mon Sep 17 00:00:00 2001 From: quippy-git Date: Fri, 8 Dec 2023 21:08:32 +0100 Subject: [PATCH] 3.7 X-Mas Release --- README.md | 74 +- .../de/quippy/javamod/main/gui/MainForm.java | 635 ++++---- .../javamod/main/gui/XmasConfigPanel.java | 121 ++ .../main/gui/XmasScreenConfigPanel.java | 325 ++++ .../main/gui/components/MeterPanelBase.java | 22 +- .../gui/components/ThreadUpdatePanel.java | 63 +- .../gui/components/XmasDecorationPanel.java | 293 ++++ .../main/gui/playlist/PlayListGUI.java | 8 +- .../main/gui/ressources/lightbulbs/0.gif | Bin 0 -> 883 bytes .../main/gui/ressources/lightbulbs/1.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/10.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/11.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/12.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/13.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/14.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/2.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/3.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/4.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/5.gif | Bin 0 -> 965 bytes .../main/gui/ressources/lightbulbs/6.gif | Bin 0 -> 968 bytes .../main/gui/ressources/lightbulbs/7.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/8.gif | Bin 0 -> 970 bytes .../main/gui/ressources/lightbulbs/9.gif | Bin 0 -> 970 bytes .../javamod/main/playlist/PlayList.java | 2 +- source/de/quippy/javamod/mixer/Mixer.java | 5 +- .../multimedia/mod/ModConfigPanel.java | 4 +- .../javamod/multimedia/mod/ModContainer.java | 12 +- .../javamod/multimedia/mod/ModInfoPanel.java | 79 +- .../javamod/multimedia/mod/ModMixer.java | 3 +- .../mod/gui/ModInstrumentDialog.java | 155 +- .../multimedia/mod/gui/ModPatternDialog.java | 1317 +++++++++++++---- .../multimedia/mod/gui/ModSampleDialog.java | 49 +- .../multimedia/mod/gui/ModUpdateListener.java | 70 +- .../mod/loader/pattern/Pattern.java | 50 +- .../mod/loader/pattern/PatternContainer.java | 42 +- .../mod/loader/pattern/PatternRow.java | 33 +- .../mod/loader/tracker/ImpulseTrackerMod.java | 11 +- .../multimedia/mod/loader/tracker/XMMod.java | 25 +- .../multimedia/mod/mixer/BasicModMixer.java | 460 ++++-- .../multimedia/mod/mixer/ProTrackerMixer.java | 215 ++- .../mod/mixer/ScreamTrackerMixer.java | 192 ++- .../quippy/javamod/system/CircularBuffer.java | 83 +- source/de/quippy/javamod/system/Helpers.java | 35 +- .../de/quippy/jmac/decoder/APEDecompress.java | 17 +- .../jmac/decoder/APEDecompressCore.java | 6 +- .../quippy/jmac/decoder/APEDecompressOld.java | 12 +- source/de/quippy/jmac/decoder/UnBitArray.java | 4 +- .../quippy/jmac/decoder/UnBitArrayBase.java | 4 +- source/de/quippy/jmac/decoder/UnMAC.java | 4 +- source/de/quippy/jmac/info/APEDescriptor.java | 6 +- source/de/quippy/jmac/info/APEHeader.java | 6 +- source/de/quippy/jmac/info/APEHeaderNew.java | 6 +- source/de/quippy/jmac/info/APEHeaderOld.java | 6 +- source/de/quippy/jmac/info/APEInfo.java | 10 +- source/de/quippy/jmac/info/APELink.java | 4 +- source/de/quippy/jmac/info/APETagField.java | 4 +- source/de/quippy/jmac/info/APETagFooter.java | 6 +- source/de/quippy/jmac/info/ID3Tag.java | 6 +- source/de/quippy/jmac/info/WaveFormat.java | 4 +- source/de/quippy/jmac/info/WaveHeader.java | 6 +- .../de/quippy/jmac/prediction/NNFilter.java | 4 +- .../PredictorDecompress3950toCurrent.java | 4 +- .../PredictorDecompressNormal3930to3950.java | 4 +- source/de/quippy/ogg/jorbis/Block.java | 3 +- source/de/quippy/ogg/jorbis/CodeBook.java | 2 +- source/de/quippy/ogg/jorbis/Comment.java | 3 +- source/de/quippy/ogg/jorbis/Floor0.java | 2 +- source/de/quippy/ogg/jorbis/Floor1.java | 2 +- source/de/quippy/ogg/jorbis/FuncFloor.java | 2 +- source/de/quippy/ogg/jorbis/FuncMapping.java | 2 +- source/de/quippy/ogg/jorbis/FuncResidue.java | 2 +- source/de/quippy/ogg/jorbis/FuncTime.java | 2 +- source/de/quippy/ogg/jorbis/Info.java | 3 +- source/de/quippy/ogg/jorbis/Mapping0.java | 2 +- source/de/quippy/ogg/jorbis/Residue0.java | 2 +- .../de/quippy/ogg/jorbis/StaticCodeBook.java | 2 +- source/de/quippy/ogg/jorbis/Time0.java | 2 +- source/de/quippy/ogg/jorbis/VorbisFile.java | 9 +- .../de/quippy/sidplay/libsidplay/Player.java | 5 +- .../quippy/sidplay/libsidplay/SIDPlay2.java | 1 + .../libsidplay/common/mos6510/MOS6510.java | 2 +- .../components/mos6526/MOS6526.java | 3 +- .../components/mos6526/SID6526.java | 3 +- .../components/mos656x/MOS656X.java | 1 + .../components/sidtune/InfoFile.java | 1 + .../libsidplay/components/sidtune/Mus.java | 1 + .../libsidplay/components/sidtune/P00.java | 1 + .../libsidplay/components/sidtune/Prg.java | 1 + .../libsidplay/components/xsid/XSID.java | 2 +- .../quippy/sidplay/resid_builder/ReSID.java | 6 +- .../sidplay/resid_builder/ReSIDBuilder.java | 2 +- .../sidplay/resid_builder/resid/Filter.java | 1 + .../resid/WaveformGenerator.java | 1 + 93 files changed, 3487 insertions(+), 1090 deletions(-) create mode 100644 source/de/quippy/javamod/main/gui/XmasConfigPanel.java create mode 100644 source/de/quippy/javamod/main/gui/XmasScreenConfigPanel.java create mode 100644 source/de/quippy/javamod/main/gui/components/XmasDecorationPanel.java create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/0.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/1.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/10.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/11.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/12.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/13.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/14.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/2.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/3.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/4.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/5.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/6.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/7.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/8.gif create mode 100644 source/de/quippy/javamod/main/gui/ressources/lightbulbs/9.gif mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Block.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/CodeBook.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Comment.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Floor0.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Floor1.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/FuncFloor.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/FuncMapping.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/FuncResidue.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/FuncTime.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Info.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Mapping0.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Residue0.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/StaticCodeBook.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/Time0.java mode change 100755 => 100644 source/de/quippy/ogg/jorbis/VorbisFile.java diff --git a/README.md b/README.md index 5488bcd..24dc5b7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# JavaMod V3.6 +# JavaMod V3.7 JavaMod - a java based multimedia player for Protracker, Fast Tracker, Impulse Tracker, Scream Tracker and other mod files plus SID, MP3, WAV, OGG, APE, FLAC, MIDI, AdLib ROL-Files (OPL), ... @@ -12,7 +12,10 @@ mode open a command line (CMD or Shell) and enter: java -jar ./javamod.jar To start the command line version enter: java -cp ./javamod.jar de.quippy.javamod.main.CommandLine MODFILE - Without any parameters you will receive a help screen. + Without any parameters you will receive a help screen. + +On Linux consider starting with OpenGL render pipeline activated: + java -Dsun.java2d.opengl=true -jar ./javamod.jar ## Download of compiled version and source code * https://javamod.de/javamod.php @@ -52,8 +55,6 @@ JavaMod incorporates modified versions of the following libraries: as here we can have a whole bunch of devices. Asynchronous loading is not an option. Lazy loading does not help as the available MidiDevices must be present when creating the config drop down list for selection. -* Clean up effects - some are for IT only, some for XM only (copy&paste...) - (Mostly done, still needs QS) * On Linux * gapless audio streams do not work if SourceLine Buffers drain out * JDialogs, when set visible, will not come to front @@ -65,6 +66,66 @@ JavaMod incorporates modified versions of the following libraries: * Midi and AdLib/OPL with Mods * read 7z archives +## New in Version 3.7 +* NEW XMAS SPECIAL: + Enjoy some light bulbs on your desktop. You can enable it in the view + menu. Select the screen, you want to decorate and select the effects and + speed per screen. + Remark: it depends on the desktop render engine how transparent windows + are rendered and if a "click through" works. On Windows this works really + flawlessly, but on KDE it is either flickery or with opengl it inherits + the dim color of a window decoration under it. +* NEW: Follow song in pattern dialog is now fun to watch: + - The arrangement is now scrolling to the activated pattern. + - In the pattern dialog horizontal scrolling by user is not reset by + caret anymore. + - no editing the caret (mark text) via mouse by user + - Rows and channels are fixed for scrolling - and added some color (yes, + a bit more gray) + - channel markers are buttons for muting and have a context menu to + select solo, mute and un-mute per channel + - resetting to normal mute will regard muted channels with ITs (if the + author wanted them to be muted) + - Added sample / panning representation in channel buttons based on + samples / volumes and panning in channel + - Coding of colored version was deleted... It is too slow anyways. + - Follow song can be switched off - however, this will only stop + automatic scrolling and pattern display. If the currently watched + pattern is played, the caret will fly by (though being of lightest + gray) + - display of current volume column effect and effect column effect + - No FollowSong while exporting - except for when doing play back while + exporting + - upper left corner shows pattern number +* NEW: Pattern/Sample/Instrument dialogs will disappear when a file other than + a mod (e.g. mp3) is played - and reappear when a mod is played again +* NEW: To make pattern sample/instrument data (hex values) fit to sample and + instrument dialog index, changed display there to hex as well +* NEW: In the instrument dialog you can now hop over to the sample mapped. Just + click in the mapping rows on the sample of choice. +* FIX: Look&Feel menu will now show active Look&Feel set +* FIX: for the FIX of the FIX... + With PortaToNote we did things a bit too easy regarding an instrument + set. (BTW: The behavior of FT2, IT2.14, Schism and ModPlug is totally + different here, which values for volume and panning reset to use.) + Three things are now done: + - if the current instrument is a long player (i.e. has loops), we will + continue using that. If no instrument is playing, we will use the new + given instrument and switch to it + - but also safe the instrument set. Following notes (without instrument) + will use exactly that new one. + - reset panning and volume to the instrument chosen from above + Check with Airborn.xm and Anthem.mod +* FIX: PatternBreak at end of Song: do a loop and start at given row, do a + fade-out if wished. Do not do so, if infinite loops are to be ignored. + (fixed spelling in GUI btw...) +* FIX: XMs: if we have a note cut, we have to store the zero volume, so a new + note without an instrument set will not be audible. +* FIX: Empty patterns with XMs and ITs are now recognized. Default empty pattern + is set for display (64 default rows with ITs) +* FIX: After loading Impulse Tracker mods reduce Patterns to real amount of + channels (we reserved 64 channels in advance for filling) + ## New in Version 3.6 * NEW: Shuffle play list moved from context menu to a separate button, so that the function is found. @@ -86,14 +147,15 @@ JavaMod incorporates modified versions of the following libraries: alter the container singleton. Changed that in 3.4 for MIDIs using "getSongName". Result: after adding a piece to the play list, this would not play when double clicked. -* FIX: Samples are now displayed without gap to the left (only visible with +* FIX: Samples are now displayed without gap to the right (only visible with small samples), color of loop was adjusted, is not swallowed by border * FIX: BasicModMixer::fitIntoLoops ping pong loops were calculated a bit off as XMs need that differently to ITs... (AGAiN - FairStars MP3 Recorderkg.XM vs. TIMEAGO.IT) * FIX: IT Compatibility: Ensure that there is no pan swing, panbrello, panning envelopes, etc. applied on surround channels. -* FIX: Looping a song needs complete reset on all and everything +* FIX: If looping is selected and forced on a song, we need to do a complete + reset on all and everything. ## New in Version 3.5 * FIX: PortaToNote: if an instrument is set, that was ignored, as FT2.09 does it. diff --git a/source/de/quippy/javamod/main/gui/MainForm.java b/source/de/quippy/javamod/main/gui/MainForm.java index 85da163..8955b9c 100644 --- a/source/de/quippy/javamod/main/gui/MainForm.java +++ b/source/de/quippy/javamod/main/gui/MainForm.java @@ -22,15 +22,21 @@ package de.quippy.javamod.main.gui; import java.awt.AWTException; +import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.DisplayMode; import java.awt.EventQueue; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; import java.awt.HeadlessException; import java.awt.Image; +import java.awt.Insets; import java.awt.MenuItem; +import java.awt.Point; import java.awt.PopupMenu; import java.awt.SystemTray; +import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.Window; import java.awt.dnd.DropTarget; @@ -41,6 +47,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; +import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowFocusListener; import java.io.File; @@ -52,13 +59,24 @@ import java.util.Iterator; import java.util.Set; +import javax.swing.ImageIcon; +import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JDialog; import javax.swing.JFileChooser; +import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.JTextField; +import javax.swing.SwingConstants; import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.WindowConstants; import javax.swing.border.BevelBorder; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; @@ -105,7 +123,7 @@ * @author Daniel Becker * @since 22.06.2006 */ -public class MainForm extends javax.swing.JFrame implements DspProcessorCallBack, PlayThreadEventListener, MultimediaContainerEventListener, PlaylistGUIChangeListener, PlaylistDropListenerCallBack +public class MainForm extends JFrame implements DspProcessorCallBack, PlayThreadEventListener, MultimediaContainerEventListener, PlaylistGUIChangeListener, PlaylistDropListenerCallBack { private static final long serialVersionUID = -2737074464335059959L; @@ -152,6 +170,9 @@ public class MainForm extends javax.swing.JFrame implements DspProcessorCallBack private static final String PROPERTY_PROPERTIESDIALOG_VISABLE = "javamod.dialog.open.properties"; private static final String PROPERTY_PLAYLIST_VISABLE = "javamod.dialog.open.playlist"; private static final String PROPERTY_EFFECT_VISABLE = "javamod.dialog.open.equalizer"; + private static final String PROPERTY_XMASCONFIGDIALOG_POS = "javamod.dialog.position.xmasconfig"; + private static final String PROPERTY_XMASCONFIGDIALOG_SIZE = "javamod.dialog.size.xmasconfig"; + private static final String PROPERTY_XMASCONFIG_VISABLE = "javamod.dialog.open.xmasconfig"; private static final String PROPERTY_EFFECTS_PASSTHROUGH = "javamod.player.effects.passthrough"; private static final String PROPERTY_EFFECTS_USEGAPLESS = "javamod.player.effects.usegapless"; @@ -172,64 +193,70 @@ public class MainForm extends javax.swing.JFrame implements DspProcessorCallBack private static FileFilter fileFilterExport[]; private static FileFilter fileFilterLoad[]; - private javax.swing.ImageIcon buttonPlay_Active = null; - private javax.swing.ImageIcon buttonPlay_Inactive = null; - private javax.swing.ImageIcon buttonPlay_normal = null; - private javax.swing.ImageIcon buttonPause_Active = null; - private javax.swing.ImageIcon buttonPause_Inactive = null; - private javax.swing.ImageIcon buttonPause_normal = null; - private javax.swing.ImageIcon buttonStop_Active = null; - private javax.swing.ImageIcon buttonStop_Inactive = null; - private javax.swing.ImageIcon buttonStop_normal = null; - private javax.swing.ImageIcon buttonPrev_Active = null; - private javax.swing.ImageIcon buttonPrev_Inactive = null; - private javax.swing.ImageIcon buttonPrev_normal = null; - private javax.swing.ImageIcon buttonNext_Active = null; - private javax.swing.ImageIcon buttonNext_Inactive = null; - private javax.swing.ImageIcon buttonNext_normal = null; + private ImageIcon buttonPlay_Active = null; + private ImageIcon buttonPlay_Inactive = null; + private ImageIcon buttonPlay_normal = null; + private ImageIcon buttonPause_Active = null; + private ImageIcon buttonPause_Inactive = null; + private ImageIcon buttonPause_normal = null; + private ImageIcon buttonStop_Active = null; + private ImageIcon buttonStop_Inactive = null; + private ImageIcon buttonStop_normal = null; + private ImageIcon buttonPrev_Active = null; + private ImageIcon buttonPrev_Inactive = null; + private ImageIcon buttonPrev_normal = null; + private ImageIcon buttonNext_Active = null; + private ImageIcon buttonNext_Inactive = null; + private ImageIcon buttonNext_normal = null; - private javax.swing.JButton button_Play = null; - private javax.swing.JButton button_Pause = null; - private javax.swing.JButton button_Stop = null; - private javax.swing.JButton button_Prev = null; - private javax.swing.JButton button_Next = null; + private JButton button_Play = null; + private JButton button_Pause = null; + private JButton button_Stop = null; + private JButton button_Prev = null; + private JButton button_Next = null; private RoundSlider volumeSlider = null; - private javax.swing.JLabel volumeLabel = null; + private JLabel volumeLabel = null; private RoundSlider balanceSlider = null; - private javax.swing.JLabel balanceLabel = null; + private JLabel balanceLabel = null; - private javax.swing.JPanel baseContentPane = null; - private javax.swing.JPanel mainContentPane = null; - private javax.swing.JPanel musicDataPane = null; - private javax.swing.JPanel playerControlPane = null; - private javax.swing.JPanel playerDataPane = null; + private JPanel baseContentPane = null; + private JPanel mainContentPane = null; + private JPanel musicDataPane = null; + private JPanel playerControlPane = null; + private JPanel playerDataPane = null; private ArrayList windowIcons = null; - private javax.swing.JDialog modInfoDialog = null; - private javax.swing.JDialog playerSetUpDialog = null; - private javax.swing.JDialog playlistDialog = null; - private javax.swing.JDialog equalizerDialog = null; + private JDialog modInfoDialog = null; + private JDialog playerSetUpDialog = null; + private JDialog playlistDialog = null; + private JDialog equalizerDialog = null; + private JDialog xmasConfigDialog = null; private PlayerConfigPanel playerConfigPanel = null; - private javax.swing.JPanel modInfoPane = null; - private javax.swing.JPanel playerSetUpPane = null; - private javax.swing.JPanel playlistPane = null; - private javax.swing.JPanel effectPane = null; + private JPanel modInfoPane = null; + private JPanel playerSetUpPane = null; + private JPanel playlistPane = null; + private JPanel effectPane = null; + private XmasConfigPanel xmasConfigPanel = null; - private java.awt.Point mainDialogLocation = null; - private java.awt.Dimension mainDialogSize = null; - private java.awt.Point modInfoDialogLocation = null; - private java.awt.Dimension modInfoDialogSize = null; + private Point mainDialogLocation = null; + private Dimension mainDialogSize = null; + private Point modInfoDialogLocation = null; + private Dimension modInfoDialogSize = null; private boolean modInfoDialogVisable = false; - private java.awt.Point playerSetUpDialogLocation = null; - private java.awt.Dimension playerSetUpDialogSize = null; + private Point playerSetUpDialogLocation = null; + private Dimension playerSetUpDialogSize = null; private boolean playerSetUpDialogVisable = false; - private java.awt.Point playlistDialogLocation = null; - private java.awt.Dimension playlistDialogSize = null; + private Point playlistDialogLocation = null; + private Dimension playlistDialogSize = null; private boolean playlistDialogVisable = false; - private java.awt.Point effectsDialogLocation = null; - private java.awt.Dimension effectsDialogSize = null; + private Point effectsDialogLocation = null; + private Dimension effectsDialogSize = null; private boolean effectDialogVisable = false; + private Point xmasConfigDialogLocation = null; + private Dimension xmasConfigDialogSize = null; + private boolean xmasConfigDialogVisable = false; + private SimpleProgressDialog downloadDialog = null; private DoubleProgressDialog exportDialog = null; @@ -242,31 +269,32 @@ public class MainForm extends javax.swing.JFrame implements DspProcessorCallBack private SeekBarPanel seekBarPanel = null; - private javax.swing.JTextField messages = null; + private JTextField messages = null; - private javax.swing.JMenuBar baseMenuBar = null; - private javax.swing.JMenu menu_File = null; - private javax.swing.JMenu menu_View = null; - private javax.swing.JMenu menu_LookAndFeel = null; - private javax.swing.JMenu menu_Help = null; - private javax.swing.JMenu menu_File_RecentFiles = null; - private javax.swing.JMenuItem menu_File_openMod = null; - private javax.swing.JMenuItem menu_File_openURL = null; - private javax.swing.JMenuItem menu_File_exportWave = null; - private javax.swing.JMenuItem menu_File_exportFromPlayList = null; - private javax.swing.JMenuItem menu_File_copyFilesInPlayListOrder = null; - private javax.swing.JMenuItem menu_File_Close = null; - private javax.swing.JMenuItem menu_View_ArrangeWindows = null; - private javax.swing.JMenuItem menu_View_Info = null; - private javax.swing.JMenuItem menu_View_Setup = null; - private javax.swing.JMenuItem menu_View_Playlist = null; - private javax.swing.JMenuItem menu_View_GraphicEQ = null; - private javax.swing.JCheckBoxMenuItem menu_View_UseSystemTray = null; - private javax.swing.JMenuItem menu_Help_CheckUpdate = null; - private javax.swing.JMenuItem menu_Help_ShowSoundHardware = null; - private javax.swing.JMenuItem menu_Help_ShowVersionHistory = null; - private javax.swing.JMenuItem menu_Help_About = null; - private javax.swing.JCheckBoxMenuItem [] menu_LookAndFeel_Items = null; + private JMenuBar baseMenuBar = null; + private JMenu menu_File = null; + private JMenu menu_View = null; + private JMenu menu_LookAndFeel = null; + private JMenu menu_Help = null; + private JMenu menu_File_RecentFiles = null; + private JMenuItem menu_File_openMod = null; + private JMenuItem menu_File_openURL = null; + private JMenuItem menu_File_exportWave = null; + private JMenuItem menu_File_exportFromPlayList = null; + private JMenuItem menu_File_copyFilesInPlayListOrder = null; + private JMenuItem menu_File_Close = null; + private JMenuItem menu_View_ArrangeWindows = null; + private JMenuItem menu_View_Info = null; + private JMenuItem menu_View_Setup = null; + private JMenuItem menu_View_Playlist = null; + private JMenuItem menu_View_GraphicEQ = null; + private JMenuItem menu_View_XMAS_mode_config = null; + private JCheckBoxMenuItem menu_View_UseSystemTray = null; + private JMenuItem menu_Help_CheckUpdate = null; + private JMenuItem menu_Help_ShowSoundHardware = null; + private JMenuItem menu_Help_ShowVersionHistory = null; + private JMenuItem menu_Help_About = null; + private JCheckBoxMenuItem [] menu_LookAndFeel_Items = null; private MenuItem aboutItem = null; private MenuItem playItem = null; @@ -311,7 +339,6 @@ public class MainForm extends javax.swing.JFrame implements DspProcessorCallBack private boolean inExportMode; private boolean useGaplessAudio; - private final class LookAndFeelChanger implements ActionListener { @@ -414,9 +441,12 @@ private void readPropertyFile() searchPath = props.getProperty(PROPERTY_SEARCHPATH, Helpers.HOMEDIR); exportPath = props.getProperty(PROPERTY_EXPORTPATH, Helpers.HOMEDIR); - uiClassName = props.getProperty(PROPERTY_LOOKANDFEEL, javax.swing.UIManager.getSystemLookAndFeelClassName()); useSystemTray = Boolean.parseBoolean(props.getProperty(PROPERTY_SYSTEMTRAY, "FALSE")); - currentVolume = Float.parseFloat(props.getProperty(PROPERTY_VOLUME_VALUE, "1.0")); + + uiClassName = props.getProperty(PROPERTY_LOOKANDFEEL, UIManager.getSystemLookAndFeelClassName()); + setLookAndFeel(uiClassName); // set the Look&Feel to be used, so when creating the menu we select the current Look&Feel set + + currentVolume = Float.parseFloat(props.getProperty(PROPERTY_VOLUME_VALUE, "1.0")); currentBalance = Float.parseFloat(props.getProperty(PROPERTY_BALANCE_VALUE, "0.0")); lastLoaded = new ArrayList(PROPERTY_LASTLOADED_MAXENTRIES); for (int i=0; i allLAFs = new java.util.ArrayList(); // allLAFs.add(new UIManager.LookAndFeelInfo("Kunststoff", "com.incors.plaf.kunststoff.KunststoffLookAndFeel")); // allLAFs.add(new UIManager.LookAndFeelInfo("Oyoaha", "com.oyoaha.swing.plaf.oyoaha.OyoahaLookAndFeel")); // allLAFs.add(new UIManager.LookAndFeelInfo("MacOS", "it.unitn.ing.swing.plaf.macos.MacOSLookAndFeel")); // allLAFs.add(new UIManager.LookAndFeelInfo("GTK", "org.gtk.java.swing.plaf.gtk.GtkLookAndFeel")); -// javax.swing.UIManager.LookAndFeelInfo [] installedLAFs = javax.swing.UIManager.getInstalledLookAndFeels(); +// UIManager.LookAndFeelInfo [] installedLAFs = UIManager.getInstalledLookAndFeels(); // for (int i=0; i(); @@ -732,12 +771,13 @@ private void createAllWindows() windows.add(getSimpleTextViewerDialog()); windows.add(getPlaylistDialog()); windows.add(getEffectDialog()); + windows.add(getXmasConfigDialog()); } /** * @param dtde * @param dropResult * @param addToLastLoaded - * @see de.quippy.javamod.main.gui.tools.PlaylistDropListenerCallBack#playlistRecieved(java.awt.dnd.DropTargetDropEvent, de.quippy.javamod.main.playlist.PlayList, java.net.URL) + * @see de.quippy.javamod.main.gui.tools.PlaylistDropListenerCallBack#playlistRecieved(dnd.DropTargetDropEvent, de.quippy.javamod.main.playlist.PlayList, java.net.URL) * @since 08.03.2011 */ public void playlistRecieved(DropTargetDropEvent dtde, PlayList dropResult, URL addToLastLoaded) @@ -779,15 +819,15 @@ private void setLookAndFeel(String lookAndFeelClassName) { try { - javax.swing.UIManager.setLookAndFeel(lookAndFeelClassName); + UIManager.setLookAndFeel(lookAndFeelClassName); } catch (Throwable e) { showMessage("The selected Look&Feel is not supported or not reachable through the classpath. Switching to system default..."); try { - lookAndFeelClassName = javax.swing.UIManager.getSystemLookAndFeelClassName(); - javax.swing.UIManager.setLookAndFeel(lookAndFeelClassName); + lookAndFeelClassName = UIManager.getSystemLookAndFeelClassName(); + UIManager.setLookAndFeel(lookAndFeelClassName); } catch (Throwable e1) { @@ -811,15 +851,27 @@ private void updateLookAndFeel(String lookAndFeelClassName) SwingUtilities.updateComponentTreeUI(window); window.pack(); } } + private JPanel oInfoPanel = null; + /** + * Change the info panel in the ModInfoPane to the new panel according + * to loading of a file. + * However, if we will set the same info panel again, do not change it. + * @since 22.06.2006 + */ private void changeInfoPane() { - getModInfoPane().removeAll(); final JPanel infoPanel = getCurrentContainer().getInfoPanel(); - if (infoPanel instanceof HasParentDialog) - ((HasParentDialog)infoPanel).setParentDialog(getModInfoDialog()); - getModInfoPane().add(infoPanel, java.awt.BorderLayout.CENTER); - getModInfoDialog().pack(); - getModInfoDialog().repaint(); + if (oInfoPanel!=infoPanel) + { + oInfoPanel = infoPanel; + if (infoPanel instanceof HasParentDialog) + ((HasParentDialog)infoPanel).setParentDialog(getModInfoDialog()); + + getModInfoPane().removeAll(); + getModInfoPane().add(infoPanel, BorderLayout.CENTER); + getModInfoDialog().pack(); + getModInfoDialog().repaint(); + } } private void changeConfigPane() { @@ -849,11 +901,11 @@ public void setDSPEnabled(boolean dspEnabled) if (audioProcessor!=null) audioProcessor.setDspEnabled(dspEnabled); } /* Element Getter Methods ---------------------------------------------- */ - public javax.swing.JMenuBar getBaseMenuBar() + public JMenuBar getBaseMenuBar() { if (baseMenuBar == null) { - baseMenuBar = new javax.swing.JMenuBar(); + baseMenuBar = new JMenuBar(); baseMenuBar.setName("baseMenuBar"); baseMenuBar.add(getMenu_File()); baseMenuBar.add(getMenu_View()); @@ -862,69 +914,71 @@ public javax.swing.JMenuBar getBaseMenuBar() } return baseMenuBar; } - public javax.swing.JMenu getMenu_File() + public JMenu getMenu_File() { if (menu_File == null) { - menu_File = new javax.swing.JMenu(); + menu_File = new JMenu(); menu_File.setName("menu_File"); menu_File.setMnemonic('f'); menu_File.setText("File"); menu_File.setFont(Helpers.getDialogFont()); menu_File.add(getMenu_File_openMod()); menu_File.add(getMenu_File_openURL()); - menu_File.add(new javax.swing.JSeparator()); + menu_File.add(new JSeparator()); menu_File.add(getMenu_File_exportWave()); menu_File.add(getMenu_File_exportFilesFromPlaylist()); menu_File.add(getMenu_File_exportFilesInPlaylistOrder()); - menu_File.add(new javax.swing.JSeparator()); + menu_File.add(new JSeparator()); menu_File.add(getMenu_File_RecentFiles()); - menu_File.add(new javax.swing.JSeparator()); + menu_File.add(new JSeparator()); menu_File.add(getMenu_File_Close()); } return menu_File; } - public javax.swing.JMenu getMenu_View() + public JMenu getMenu_View() { if (menu_View == null) { - menu_View = new javax.swing.JMenu(); + menu_View = new JMenu(); menu_View.setName("menu_View"); menu_View.setMnemonic('v'); menu_View.setText("View"); menu_View.setFont(Helpers.getDialogFont()); menu_View.add(getMenu_View_ArrangeWindows()); - menu_View.add(new javax.swing.JSeparator()); + menu_View.add(new JSeparator()); menu_View.add(getMenu_View_Info()); menu_View.add(getMenu_View_Setup()); menu_View.add(getMenu_View_Playlist()); menu_View.add(getMenu_View_GraphicEQ()); - menu_View.add(new javax.swing.JSeparator()); + menu_View.add(new JSeparator()); + menu_View.add(getMenu_View_XMAS_mode_config()); + menu_View.add(new JSeparator()); menu_View.add(getMenu_View_UseSystemTray()); } return menu_View; } - public javax.swing.JMenu getMenu_LookAndFeel() + public JMenu getMenu_LookAndFeel() { if (menu_LookAndFeel == null) { - menu_LookAndFeel = new javax.swing.JMenu(); + menu_LookAndFeel = new JMenu(); menu_LookAndFeel.setName("menu_LookAndFeel"); menu_LookAndFeel.setMnemonic('l'); menu_LookAndFeel.setText("Look&Feel"); menu_LookAndFeel.setFont(Helpers.getDialogFont()); - String currentUIClassName = javax.swing.UIManager.getLookAndFeel().getClass().getName(); - javax.swing.UIManager.LookAndFeelInfo [] lookAndFeels = getInstalledLookAndFeels(); - menu_LookAndFeel_Items = new javax.swing.JCheckBoxMenuItem[lookAndFeels.length]; + final String currentUIClassName = UIManager.getLookAndFeel().getClass().getName(); + UIManager.LookAndFeelInfo [] lookAndFeels = getInstalledLookAndFeels(); + menu_LookAndFeel_Items = new JCheckBoxMenuItem[lookAndFeels.length]; for (int i=0; i getWindowIconImages(String path) final java.net.URL iconURL = MainForm.class.getResource(path); if (iconURL!=null) { - final Image tempImage = java.awt.Toolkit.getDefaultToolkit().getImage(iconURL); + final Image tempImage = Toolkit.getDefaultToolkit().getImage(iconURL); // The icon is not quadratic so to keep aspect ratio, the smaller width is set to -1 windowIcons = new ArrayList(); // Create some typical dimensions of our Icon for Java to use. @@ -1577,41 +1650,41 @@ private ArrayList getWindowIconImages(String path) } return windowIcons; } - public javax.swing.JPanel getBaseContentPane() + public JPanel getBaseContentPane() { if (baseContentPane==null) { - baseContentPane = new javax.swing.JPanel(); + baseContentPane = new JPanel(); baseContentPane.setName("baseContentPane"); - baseContentPane.setLayout(new java.awt.BorderLayout()); + baseContentPane.setLayout(new BorderLayout()); - baseContentPane.add(getMessages(), java.awt.BorderLayout.SOUTH); - baseContentPane.add(getMainContentPane(), java.awt.BorderLayout.CENTER); + baseContentPane.add(getMessages(), BorderLayout.SOUTH); + baseContentPane.add(getMainContentPane(), BorderLayout.CENTER); } return baseContentPane; } - public javax.swing.JTextField getMessages() + public JTextField getMessages() { if (messages==null) { - messages = new javax.swing.JTextField(); + messages = new JTextField(); messages.setName("messages"); messages.setEditable(false); messages.setFont(Helpers.getDialogFont()); } return messages; } - public javax.swing.JPanel getMainContentPane() + public JPanel getMainContentPane() { if (mainContentPane==null) { - mainContentPane = new javax.swing.JPanel(); + mainContentPane = new JPanel(); mainContentPane.setName("mainContentPane"); - mainContentPane.setLayout(new java.awt.GridBagLayout()); + mainContentPane.setLayout(new GridBagLayout()); - mainContentPane.add(getMusicDataPane(), Helpers.getGridBagConstraint(0, 0, 1, 0, java.awt.GridBagConstraints.BOTH, java.awt.GridBagConstraints.CENTER, 0.0, 1.0)); - mainContentPane.add(getPlayerDataPane(), Helpers.getGridBagConstraint(0, 1, 1, 0, java.awt.GridBagConstraints.BOTH, java.awt.GridBagConstraints.CENTER, 0.0, 1.0)); - mainContentPane.add(getPlayerControlPane(), Helpers.getGridBagConstraint(0, 2, 1, 0, java.awt.GridBagConstraints.BOTH, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); + mainContentPane.add(getMusicDataPane(), Helpers.getGridBagConstraint(0, 0, 1, 0, GridBagConstraints.BOTH, GridBagConstraints.CENTER, 0.0, 1.0)); + mainContentPane.add(getPlayerDataPane(), Helpers.getGridBagConstraint(0, 1, 1, 0, GridBagConstraints.BOTH, GridBagConstraints.CENTER, 0.0, 1.0)); + mainContentPane.add(getPlayerControlPane(), Helpers.getGridBagConstraint(0, 2, 1, 0, GridBagConstraints.BOTH, GridBagConstraints.CENTER, 0.0, 0.0)); } return mainContentPane; } @@ -1637,7 +1710,7 @@ private UrlDialog getURLDialog() urlDialog.setLocation(Helpers.getFrameCenteredLocation(urlDialog, this)); return urlDialog; } - public javax.swing.JDialog getEffectDialog() + public JDialog getEffectDialog() { if (equalizerDialog==null) { @@ -1653,7 +1726,24 @@ public javax.swing.JDialog getEffectDialog() } return equalizerDialog; } - public javax.swing.JDialog getPlayerSetUpDialog() + public JDialog getXmasConfigDialog() + { + if (xmasConfigDialog==null) + { + xmasConfigDialog = new JDialog(this, false); + xmasConfigDialog.setTitle("X-Mas config"); + xmasConfigDialog.setName("equalizerDialog"); + xmasConfigDialog.setSize(xmasConfigDialogSize); + xmasConfigDialog.setPreferredSize(xmasConfigDialogSize); + xmasConfigDialog.setContentPane(getXmasConfigPanel()); + if (xmasConfigDialogLocation == null || (xmasConfigDialogLocation.getX()==-1 || xmasConfigDialogLocation.getY()==-1)) + xmasConfigDialogLocation = Helpers.getFrameCenteredLocation(xmasConfigDialog, null); + xmasConfigDialog.setLocation(xmasConfigDialogLocation); + xmasConfigDialog.addWindowFocusListener(makeMainWindowVisiable); + } + return xmasConfigDialog; + } + public JDialog getPlayerSetUpDialog() { if (playerSetUpDialog==null) { @@ -1669,7 +1759,7 @@ public javax.swing.JDialog getPlayerSetUpDialog() } return playerSetUpDialog; } - public javax.swing.JDialog getModInfoDialog() + public JDialog getModInfoDialog() { if (modInfoDialog==null) { @@ -1685,19 +1775,19 @@ public javax.swing.JDialog getModInfoDialog() } return modInfoDialog; } - public javax.swing.JPanel getModInfoPane() + public JPanel getModInfoPane() { if (modInfoPane==null) { - modInfoPane = new javax.swing.JPanel(); + modInfoPane = new JPanel(); modInfoPane.setName("ModInfoPane"); - modInfoPane.setLayout(new java.awt.BorderLayout()); + modInfoPane.setLayout(new BorderLayout()); modInfoPane.setBorder(new TitledBorder(null, "Multimedia File Info", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, Helpers.getDialogFont(), null)); changeInfoPane(); } return modInfoPane; } - public javax.swing.JDialog getPlaylistDialog() + public JDialog getPlaylistDialog() { if (playlistDialog==null) { @@ -1713,13 +1803,13 @@ public javax.swing.JDialog getPlaylistDialog() } return playlistDialog; } - public javax.swing.JPanel getPlaylistPane() + public JPanel getPlaylistPane() { if (playlistPane==null) { - playlistPane = new javax.swing.JPanel(); + playlistPane = new JPanel(); playlistPane.setName("playlistPane"); - playlistPane.setLayout(new java.awt.BorderLayout()); + playlistPane.setLayout(new BorderLayout()); playlistPane.setBorder(new TitledBorder(null, "Playlist", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, Helpers.getDialogFont(), null)); playlistPane.add(getPlaylistGUI()); } @@ -1734,18 +1824,29 @@ public PlayListGUI getPlaylistGUI() } return playlistGUI; } - public javax.swing.JPanel getEffectPane() + public JPanel getEffectPane() { if (effectPane==null) { - effectPane = new javax.swing.JPanel(); + effectPane = new JPanel(); effectPane.setName("effectPane"); - effectPane.setLayout(new java.awt.BorderLayout()); + effectPane.setLayout(new BorderLayout()); effectPane.setBorder(new TitledBorder(null, "Effects", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, Helpers.getDialogFont(), null)); effectPane.add(getEffectsPanel()); } return effectPane; } + public XmasConfigPanel getXmasConfigPanel() + { + if (xmasConfigPanel==null) + { + DisplayMode mode = Helpers.getScreenInfoOf(this); + final int refreshRate = (mode!=null)?mode.getRefreshRate():60; + xmasConfigPanel = new XmasConfigPanel(refreshRate); + xmasConfigPanel.setName("xmasConfigPane"); + } + return xmasConfigPanel; + } private GraphicEqGUI getEqualizerGui() { if (equalizerGUI==null) @@ -1766,7 +1867,7 @@ public EffectsPanel getEffectsPanel() { if (effectGUI==null) { - javax.swing.JPanel [] effectPanels = + JPanel [] effectPanels = { getEqualizerGui(), getPitchShiftGui() @@ -1775,13 +1876,13 @@ public EffectsPanel getEffectsPanel() } return effectGUI; } - public javax.swing.JPanel getPlayerSetUpPane() + public JPanel getPlayerSetUpPane() { if (playerSetUpPane==null) { - playerSetUpPane = new javax.swing.JPanel(); + playerSetUpPane = new JPanel(); playerSetUpPane.setName("playerSetUpPane"); - playerSetUpPane.setLayout(new java.awt.BorderLayout()); + playerSetUpPane.setLayout(new BorderLayout()); playerSetUpPane.setBorder(new TitledBorder(null, "Mixer Control", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, Helpers.getDialogFont(), null)); playerSetUpPane.add(getPlayerConfigPanel()); changeConfigPane(); @@ -1888,16 +1989,16 @@ public VUMeterPanel getVURMeterPanel() } return vuRMeterPanel; } - public javax.swing.JPanel getMusicDataPane() + public JPanel getMusicDataPane() { if (musicDataPane==null) { - musicDataPane = new javax.swing.JPanel(); + musicDataPane = new JPanel(); musicDataPane.setName("musicDataPane"); - musicDataPane.setLayout(new java.awt.GridBagLayout()); + musicDataPane.setLayout(new GridBagLayout()); musicDataPane.setBorder(new TitledBorder(null, "Name", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, Helpers.getDialogFont(), null)); - musicDataPane.add(getLEDScrollPanel(), Helpers.getGridBagConstraint(0, 0, 1, 0, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); + musicDataPane.add(getLEDScrollPanel(), Helpers.getGridBagConstraint(0, 0, 1, 0, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); } return musicDataPane; } @@ -1919,41 +2020,41 @@ public LEDScrollPanel getLEDScrollPanel() } return ledScrollPanel; } - public javax.swing.JPanel getPlayerDataPane() + public JPanel getPlayerDataPane() { if (playerDataPane==null) { - playerDataPane = new javax.swing.JPanel(); + playerDataPane = new JPanel(); playerDataPane.setName("playerDataPane"); - playerDataPane.setLayout(new java.awt.GridBagLayout()); + playerDataPane.setLayout(new GridBagLayout()); playerDataPane.setBorder(new TitledBorder(null, "Player Data", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, Helpers.getDialogFont(), null)); - playerDataPane.add(getVULMeterPanel(), Helpers.getGridBagConstraint(0, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerDataPane.add(getSALMeterPanel(), Helpers.getGridBagConstraint(1, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerDataPane.add(getSARMeterPanel(), Helpers.getGridBagConstraint(2, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerDataPane.add(getVURMeterPanel(), Helpers.getGridBagConstraint(3, 0, 1, 0, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); + playerDataPane.add(getVULMeterPanel(), Helpers.getGridBagConstraint(0, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerDataPane.add(getSALMeterPanel(), Helpers.getGridBagConstraint(1, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerDataPane.add(getSARMeterPanel(), Helpers.getGridBagConstraint(2, 0, 1, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerDataPane.add(getVURMeterPanel(), Helpers.getGridBagConstraint(3, 0, 1, 0, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); } return playerDataPane; } - public javax.swing.JPanel getPlayerControlPane() + public JPanel getPlayerControlPane() { if (playerControlPane==null) { - playerControlPane = new javax.swing.JPanel(); + playerControlPane = new JPanel(); playerControlPane.setName("playerControlPane"); - playerControlPane.setLayout(new java.awt.GridBagLayout()); + playerControlPane.setLayout(new GridBagLayout()); playerControlPane.setBorder(new TitledBorder(null, "Player Control", TitledBorder.LEADING, TitledBorder.DEFAULT_POSITION, Helpers.getDialogFont(), null)); - playerControlPane.add(getButton_Prev(), Helpers.getGridBagConstraint(0, 0, 2, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerControlPane.add(getButton_Play(), Helpers.getGridBagConstraint(1, 0, 2, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerControlPane.add(getButton_Next(), Helpers.getGridBagConstraint(2, 0, 2, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerControlPane.add(getButton_Pause(), Helpers.getGridBagConstraint(3, 0, 2, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerControlPane.add(getButton_Stop(), Helpers.getGridBagConstraint(4, 0, 2, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerControlPane.add(getVolumeSlider(), Helpers.getGridBagConstraint(5, 0, 1, 1, java.awt.GridBagConstraints.VERTICAL, java.awt.GridBagConstraints.CENTER, 0.0, 1.0)); - playerControlPane.add(getBalanceSlider(), Helpers.getGridBagConstraint(6, 0, 1, 0, java.awt.GridBagConstraints.VERTICAL, java.awt.GridBagConstraints.CENTER, 0.0, 1.0)); - playerControlPane.add(getVolumeLabel(), Helpers.getGridBagConstraint(5, 1, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerControlPane.add(getBalanceLabel(), Helpers.getGridBagConstraint(6, 1, 1, 0, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); - playerControlPane.add(getSeekBarPanel(), Helpers.getGridBagConstraint(0, 2, 1, 0, java.awt.GridBagConstraints.BOTH, java.awt.GridBagConstraints.CENTER, 1.0, 1.0)); + playerControlPane.add(getButton_Prev(), Helpers.getGridBagConstraint(0, 0, 2, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerControlPane.add(getButton_Play(), Helpers.getGridBagConstraint(1, 0, 2, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerControlPane.add(getButton_Next(), Helpers.getGridBagConstraint(2, 0, 2, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerControlPane.add(getButton_Pause(), Helpers.getGridBagConstraint(3, 0, 2, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerControlPane.add(getButton_Stop(), Helpers.getGridBagConstraint(4, 0, 2, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerControlPane.add(getVolumeSlider(), Helpers.getGridBagConstraint(5, 0, 1, 1, GridBagConstraints.VERTICAL, GridBagConstraints.CENTER, 0.0, 1.0)); + playerControlPane.add(getBalanceSlider(), Helpers.getGridBagConstraint(6, 0, 1, 0, GridBagConstraints.VERTICAL, GridBagConstraints.CENTER, 0.0, 1.0)); + playerControlPane.add(getVolumeLabel(), Helpers.getGridBagConstraint(5, 1, 1, 1, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerControlPane.add(getBalanceLabel(), Helpers.getGridBagConstraint(6, 1, 1, 0, GridBagConstraints.NONE, GridBagConstraints.CENTER, 0.0, 0.0)); + playerControlPane.add(getSeekBarPanel(), Helpers.getGridBagConstraint(0, 2, 1, 0, GridBagConstraints.BOTH, GridBagConstraints.CENTER, 1.0, 1.0)); } return playerControlPane; } @@ -1977,24 +2078,24 @@ public void valuesChanged(long milliseconds) } return seekBarPanel; } - private javax.swing.JButton getButton_Play() + private JButton getButton_Play() { if (button_Play == null) { - buttonPlay_normal = new javax.swing.ImageIcon(getClass().getResource(BUTTONPLAY_NORMAL)); - buttonPlay_Inactive = new javax.swing.ImageIcon(getClass().getResource(BUTTONPLAY_INACTIVE)); - buttonPlay_Active = new javax.swing.ImageIcon(getClass().getResource(BUTTONPLAY_ACTIVE)); + buttonPlay_normal = new ImageIcon(getClass().getResource(BUTTONPLAY_NORMAL)); + buttonPlay_Inactive = new ImageIcon(getClass().getResource(BUTTONPLAY_INACTIVE)); + buttonPlay_Active = new ImageIcon(getClass().getResource(BUTTONPLAY_ACTIVE)); - button_Play = new javax.swing.JButton(); + button_Play = new JButton(); button_Play.setName("button_Play"); button_Play.setText(Helpers.EMPTY_STING); button_Play.setToolTipText("play"); - button_Play.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - button_Play.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + button_Play.setHorizontalTextPosition(SwingConstants.CENTER); + button_Play.setVerticalTextPosition(SwingConstants.BOTTOM); button_Play.setIcon(buttonPlay_normal); button_Play.setDisabledIcon(buttonPlay_Inactive); button_Play.setPressedIcon(buttonPlay_Active); - button_Play.setMargin(new java.awt.Insets(4, 6, 4, 6)); + button_Play.setMargin(new Insets(4, 6, 4, 6)); button_Play.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -2005,24 +2106,24 @@ public void actionPerformed(ActionEvent e) } return button_Play; } - private javax.swing.JButton getButton_Pause() + private JButton getButton_Pause() { if (button_Pause == null) { - buttonPause_normal = new javax.swing.ImageIcon(getClass().getResource(BUTTONPAUSE_NORMAL)); - buttonPause_Inactive = new javax.swing.ImageIcon(getClass().getResource(BUTTONPAUSE_INACTIVE)); - buttonPause_Active = new javax.swing.ImageIcon(getClass().getResource(BUTTONPAUSE_ACTIVE)); + buttonPause_normal = new ImageIcon(getClass().getResource(BUTTONPAUSE_NORMAL)); + buttonPause_Inactive = new ImageIcon(getClass().getResource(BUTTONPAUSE_INACTIVE)); + buttonPause_Active = new ImageIcon(getClass().getResource(BUTTONPAUSE_ACTIVE)); - button_Pause = new javax.swing.JButton(); + button_Pause = new JButton(); button_Pause.setName("button_Pause"); button_Pause.setText(Helpers.EMPTY_STING); button_Pause.setToolTipText("pause"); - button_Pause.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - button_Pause.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + button_Pause.setHorizontalTextPosition(SwingConstants.CENTER); + button_Pause.setVerticalTextPosition(SwingConstants.BOTTOM); button_Pause.setIcon(buttonPause_normal); button_Pause.setDisabledIcon(buttonPause_Inactive); button_Pause.setPressedIcon(buttonPause_Active); - button_Pause.setMargin(new java.awt.Insets(4, 6, 4, 6)); + button_Pause.setMargin(new Insets(4, 6, 4, 6)); button_Pause.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -2033,24 +2134,24 @@ public void actionPerformed(ActionEvent e) } return button_Pause; } - private javax.swing.JButton getButton_Stop() + private JButton getButton_Stop() { if (button_Stop == null) { - buttonStop_normal = new javax.swing.ImageIcon(getClass().getResource(BUTTONSTOP_NORMAL)); - buttonStop_Inactive = new javax.swing.ImageIcon(getClass().getResource(BUTTONSTOP_INACTIVE)); - buttonStop_Active = new javax.swing.ImageIcon(getClass().getResource(BUTTONSTOP_ACTIVE)); + buttonStop_normal = new ImageIcon(getClass().getResource(BUTTONSTOP_NORMAL)); + buttonStop_Inactive = new ImageIcon(getClass().getResource(BUTTONSTOP_INACTIVE)); + buttonStop_Active = new ImageIcon(getClass().getResource(BUTTONSTOP_ACTIVE)); - button_Stop = new javax.swing.JButton(); + button_Stop = new JButton(); button_Stop.setName("button_Stop"); button_Stop.setText(Helpers.EMPTY_STING); button_Stop.setToolTipText("stop"); - button_Stop.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - button_Stop.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + button_Stop.setHorizontalTextPosition(SwingConstants.CENTER); + button_Stop.setVerticalTextPosition(SwingConstants.BOTTOM); button_Stop.setIcon(buttonStop_normal); button_Stop.setDisabledIcon(buttonStop_Inactive); button_Stop.setPressedIcon(buttonStop_Active); - button_Stop.setMargin(new java.awt.Insets(4, 6, 4, 6)); + button_Stop.setMargin(new Insets(4, 6, 4, 6)); button_Stop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -2061,24 +2162,24 @@ public void actionPerformed(ActionEvent e) } return button_Stop; } - private javax.swing.JButton getButton_Prev() + private JButton getButton_Prev() { if (button_Prev == null) { - buttonPrev_normal = new javax.swing.ImageIcon(getClass().getResource(BUTTONPREV_NORMAL)); - buttonPrev_Inactive = new javax.swing.ImageIcon(getClass().getResource(BUTTONPREV_INACTIVE)); - buttonPrev_Active = new javax.swing.ImageIcon(getClass().getResource(BUTTONPREV_ACTIVE)); + buttonPrev_normal = new ImageIcon(getClass().getResource(BUTTONPREV_NORMAL)); + buttonPrev_Inactive = new ImageIcon(getClass().getResource(BUTTONPREV_INACTIVE)); + buttonPrev_Active = new ImageIcon(getClass().getResource(BUTTONPREV_ACTIVE)); - button_Prev = new javax.swing.JButton(); + button_Prev = new JButton(); button_Prev.setName("button_Prev"); button_Prev.setText(Helpers.EMPTY_STING); button_Prev.setToolTipText("previous"); - button_Prev.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - button_Prev.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + button_Prev.setHorizontalTextPosition(SwingConstants.CENTER); + button_Prev.setVerticalTextPosition(SwingConstants.BOTTOM); button_Prev.setIcon(buttonPrev_normal); button_Prev.setDisabledIcon(buttonPrev_Inactive); button_Prev.setPressedIcon(buttonPrev_Active); - button_Prev.setMargin(new java.awt.Insets(4, 6, 4, 6)); + button_Prev.setMargin(new Insets(4, 6, 4, 6)); button_Prev.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -2089,24 +2190,24 @@ public void actionPerformed(ActionEvent e) } return button_Prev; } - private javax.swing.JButton getButton_Next() + private JButton getButton_Next() { if (button_Next == null) { - buttonNext_normal = new javax.swing.ImageIcon(getClass().getResource(BUTTONNEXT_NORMAL)); - buttonNext_Inactive = new javax.swing.ImageIcon(getClass().getResource(BUTTONNEXT_INACTIVE)); - buttonNext_Active = new javax.swing.ImageIcon(getClass().getResource(BUTTONNEXT_ACTIVE)); + buttonNext_normal = new ImageIcon(getClass().getResource(BUTTONNEXT_NORMAL)); + buttonNext_Inactive = new ImageIcon(getClass().getResource(BUTTONNEXT_INACTIVE)); + buttonNext_Active = new ImageIcon(getClass().getResource(BUTTONNEXT_ACTIVE)); - button_Next = new javax.swing.JButton(); + button_Next = new JButton(); button_Next.setName("button_Next"); button_Next.setText(Helpers.EMPTY_STING); button_Next.setToolTipText("next"); - button_Next.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); - button_Next.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + button_Next.setHorizontalTextPosition(SwingConstants.CENTER); + button_Next.setVerticalTextPosition(SwingConstants.BOTTOM); button_Next.setIcon(buttonNext_normal); button_Next.setDisabledIcon(buttonNext_Inactive); button_Next.setPressedIcon(buttonNext_Active); - button_Next.setMargin(new java.awt.Insets(4, 6, 4, 6)); + button_Next.setMargin(new Insets(4, 6, 4, 6)); button_Next.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) @@ -2117,7 +2218,7 @@ public void actionPerformed(ActionEvent e) } return button_Next; } - public javax.swing.JLabel getVolumeLabel() + public JLabel getVolumeLabel() { if (volumeLabel==null) { @@ -2165,7 +2266,7 @@ public void stateChanged(ChangeEvent e) } return volumeSlider; } - public javax.swing.JLabel getBalanceLabel() + public JLabel getBalanceLabel() { if (balanceLabel==null) { @@ -2304,15 +2405,20 @@ private void doClose() doDeIconify(); doStopPlaying(); - getSeekBarPanel().pauseThread(); - getVULMeterPanel().pauseThread(); - getVURMeterPanel().pauseThread(); - getSALMeterPanel().pauseThread(); - getSARMeterPanel().pauseThread(); - getLEDScrollPanel().pauseThread(); + + // Stop update threads on all ThreadUpdatePanels + getSeekBarPanel().stopThread(); + getVULMeterPanel().stopThread(); + getVURMeterPanel().stopThread(); + getSALMeterPanel().stopThread(); + getSARMeterPanel().stopThread(); + getLEDScrollPanel().stopThread(); + getXmasConfigPanel().stopThreads(); + + // Write the property file writePropertyFile(); + // remove listeners if (audioProcessor!=null) audioProcessor.removeListener(this); - MultimediaContainerManager.removeMultimediaContainerEventListener(this); MultimediaContainerManager.cleanUpAllContainers(); @@ -2989,15 +3095,4 @@ public void run() } }); } - /** - * Shows the errormessage - * - * @since 22.06.2006 - * @param error - */ -// private void showMessage(Throwable ex) -// { -// showMessage(ex.toString()); -// ex.printStackTrace(System.err); -// } } diff --git a/source/de/quippy/javamod/main/gui/XmasConfigPanel.java b/source/de/quippy/javamod/main/gui/XmasConfigPanel.java new file mode 100644 index 0000000..d9501dc --- /dev/null +++ b/source/de/quippy/javamod/main/gui/XmasConfigPanel.java @@ -0,0 +1,121 @@ +/* + * @(#) XmasConfigPanel.java + * + * Created on 05.12.2023 by Daniel Becker + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ +package de.quippy.javamod.main.gui; + +import java.awt.DisplayMode; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.util.Properties; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; + +import de.quippy.javamod.system.Helpers; + +/** + * @author Daniel Becker + * @since 05.12.2023 + */ +public class XmasConfigPanel extends JPanel +{ + private static final long serialVersionUID = 4069039567731397482L; + + private static final String BULBS_PATH = "/de/quippy/javamod/main/gui/ressources/lightbulbs/"; + private static final int ANZ_BULBS = 15; + + private JTabbedPane screenSelectionPanel = null; + private XmasScreenConfigPanel [] xmasScreenConfigPanels = null; + + private int screenFPS; + private ImageIcon[] bulbs; + private GraphicsDevice[] screens; + + /** + * Constructor for XmasConfigPanel + */ + public XmasConfigPanel(final int myDesiredFPS) + { + super(); + loadBulbs(); + screenFPS = myDesiredFPS; + screens = getScreens(); + initialize(); + } + private static GraphicsDevice[] getScreens() + { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + return ge.getScreenDevices(); + } + private void loadBulbs() + { + bulbs = new ImageIcon[ANZ_BULBS]; + for (int i=0; i flickerTypeSelector = null; + private JSlider updateFPSSelector = null; + + private JWindow transparentJFrame = null; + private XmasDecorationPanel xmasDecorationPanel = null; + + private int screenFPS; + private ImageIcon[] bulbs; + private GraphicsDevice screen; + private int defaultScreenHeight; + + /** + * Constructor for XmasScreenConfigPanel + */ + public XmasScreenConfigPanel(final int myDesiredFPS, ImageIcon[] allBulbs, GraphicsDevice forScreen) + { + super(); + screenFPS = myDesiredFPS; + bulbs = allBulbs; + screen=forScreen; + defaultScreenHeight = (bulbs!=null && bulbs[0]!=null)?bulbs[0].getIconHeight():32; + initialize(); + } + private void initialize() + { + setName("Xmas Screen Config for Screen"); + setLayout(new java.awt.GridBagLayout()); + add(getXmasEnabledCheckBox(), Helpers.getGridBagConstraint(0, 0, 1, 3, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); + add(getWithSpaceCheckBox(), Helpers.getGridBagConstraint(0, 1, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); + add(getFlickerTypeLabel(), Helpers.getGridBagConstraint(1, 1, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); + add(getFlickerTypeSelector(), Helpers.getGridBagConstraint(2, 1, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); + add(getUpdateFPSLabel(), Helpers.getGridBagConstraint(0, 2, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); + add(getUpdateFPSSelector(), Helpers.getGridBagConstraint(1, 2, 1, 2, java.awt.GridBagConstraints.HORIZONTAL, java.awt.GridBagConstraints.WEST, 1.0, 0.0)); + } + private JCheckBox getXmasEnabledCheckBox() + { + if (xmasEnabledCheckBox == null) + { + xmasEnabledCheckBox = new javax.swing.JCheckBox(); + xmasEnabledCheckBox.setName("xmasEnabledCheckBox"); + xmasEnabledCheckBox.setText("Enable X-Mas decoration on this screen"); + xmasEnabledCheckBox.setFont(Helpers.getDialogFont()); + xmasEnabledCheckBox.setSelected(isXmasEnabled()); + xmasEnabledCheckBox.addItemListener(new ItemListener() + { + public void itemStateChanged(ItemEvent e) + { + if (e.getStateChange()==ItemEvent.SELECTED || e.getStateChange()==ItemEvent.DESELECTED) + { + final boolean isEnabled = getXmasEnabledCheckBox().isSelected(); + getTransparentJFrame().setVisible(isEnabled); + if (isEnabled) startThread(); // else: do not stop the thread - that cannot be undone + } + } + }); + } + return xmasEnabledCheckBox; + } + private JCheckBox getWithSpaceCheckBox() + { + if (withSpaceCheckBox == null) + { + withSpaceCheckBox = new javax.swing.JCheckBox(); + withSpaceCheckBox.setName("withSpaceCheckBox"); + withSpaceCheckBox.setText("with Space"); + withSpaceCheckBox.setFont(Helpers.getDialogFont()); + withSpaceCheckBox.setSelected(isWithSpaceEnabled()); + withSpaceCheckBox.addItemListener(new ItemListener() + { + public void itemStateChanged(ItemEvent e) + { + if (e.getStateChange()==ItemEvent.SELECTED || e.getStateChange()==ItemEvent.DESELECTED) + { + getXmasDecorationPanel().setWithSpace(getWithSpaceCheckBox().isSelected()); + } + } + }); + } + return withSpaceCheckBox; + } + private JLabel getFlickerTypeLabel() + { + if (flickerTypeLabel == null) + { + flickerTypeLabel = new JLabel("Effect type:"); + flickerTypeLabel.setName("flickerTypeLabel"); + flickerTypeLabel.setFont(Helpers.getDialogFont()); + } + return flickerTypeLabel; + } + private JComboBox getFlickerTypeSelector() + { + if (flickerTypeSelector==null) + { + flickerTypeSelector = new JComboBox(); + flickerTypeSelector.setName("flickerTypeSelector"); + + DefaultComboBoxModel theModel = new DefaultComboBoxModel(XmasDecorationPanel.FLICKER_TYPES); + flickerTypeSelector.setModel(theModel); + flickerTypeSelector.setFont(Helpers.getDialogFont()); + flickerTypeSelector.setEnabled(true); + flickerTypeSelector.addItemListener(new ItemListener() + { + public void itemStateChanged(ItemEvent e) + { + if (e.getStateChange()==ItemEvent.SELECTED) + { + getXmasDecorationPanel().setFlickerType(getFlickerType()); + } + } + }); + } + return flickerTypeSelector; + } + private JLabel getUpdateFPSLabel() + { + if (updateFPSLabel == null) + { + updateFPSLabel = new JLabel("Updates per second:"); + updateFPSLabel.setName("updateFPSLabel"); + updateFPSLabel.setFont(Helpers.getDialogFont()); + } + return updateFPSLabel; + } + private JSlider getUpdateFPSSelector() + { + if (updateFPSSelector==null) + { + updateFPSSelector = new JSlider(JSlider.HORIZONTAL, 0, screenFPS, 1); + updateFPSSelector.setFont(Helpers.getDialogFont()); + updateFPSSelector.setMinorTickSpacing(1); + updateFPSSelector.setMajorTickSpacing(10); + updateFPSSelector.setPaintTicks(true); + updateFPSSelector.setSnapToTicks(true); + updateFPSSelector.setPaintLabels(false); + updateFPSSelector.setPaintTrack(true); + updateFPSSelector.setToolTipText(Integer.toString(updateFPSSelector.getValue())); + updateFPSSelector.addMouseListener(new MouseAdapter() + { + public void mouseClicked(MouseEvent e) + { + if (e.getClickCount()>1) + { + ((JSlider)e.getSource()).setValue(2); + e.consume(); + } + } + }); + updateFPSSelector.addChangeListener(new ChangeListener() + { + @Override + public void stateChanged(ChangeEvent e) + { + getUpdateFPSSelector().setToolTipText(Integer.toString(getUpdateFPSSelector().getValue())); + getXmasDecorationPanel().setUpdateFPS(getUpdateFPSSelector().getValue()); + } + }); + } + return updateFPSSelector; + } + private JWindow getTransparentJFrame() + { + // Examples use always a java.awt.Window for this. That basically does work. + // But whatever the difference of a JWindow to a Window is, a Window + // does not work with the OpenGL render pipeline. + // On Linux / KDE the OpenGL pipeline reduces flicker, however the + // Window inherits the alpha value of the underlying window... + if (transparentJFrame == null) + { + transparentJFrame = new JWindow(); + transparentJFrame.setAlwaysOnTop(true); + + final GraphicsConfiguration gc = screen.getDefaultConfiguration(); + final Rectangle bounds = gc.getBounds(); + bounds.height = defaultScreenHeight; + transparentJFrame.setBounds(bounds); + + transparentJFrame.setBackground(new Color(0, true)); + transparentJFrame.setContentPane(getXmasDecorationPanel()); + transparentJFrame.setFocusable(false); + transparentJFrame.setFocusableWindowState(false); + } + return transparentJFrame; + } + private XmasDecorationPanel getXmasDecorationPanel() + { + if (xmasDecorationPanel==null) + { + xmasDecorationPanel = new XmasDecorationPanel(screenFPS, bulbs); + xmasDecorationPanel.setBorder(BorderFactory.createEmptyBorder()); + xmasDecorationPanel.setOpaque(false); + xmasDecorationPanel.setBackground(new Color(0, true)); + final Dimension d = getTransparentJFrame().getSize(); + xmasDecorationPanel.setSize(d); + } + return xmasDecorationPanel; + } + private boolean isXmasEnabled() + { + return getXmasEnabledCheckBox().isSelected(); + } + private void setXmasEnabled(final boolean xmasEnabled) + { + getXmasEnabledCheckBox().setSelected(xmasEnabled); + } + private boolean isWithSpaceEnabled() + { + return getWithSpaceCheckBox().isSelected(); + } + private void setWithSpaceEnabled(final boolean spaceEnabled) + { + getWithSpaceCheckBox().setSelected(spaceEnabled); + } + private void setFlickerType(final int newFlickerType) + { + if (newFlickerType>=0 && newFlickerType=getUpdateFPSSelector().getMinimum() && newUpdateFPS<=getUpdateFPSSelector().getMaximum()) + getUpdateFPSSelector().setValue(newUpdateFPS); + } + private int getUpdateFPS() + { + return getUpdateFPSSelector().getValue(); + } + +//---------------------- public interface -------------------------------------- + + public void readProperties(final Properties props, final int forScreen) + { + final String index = '.'+Integer.toString(forScreen); + setFlickerType(Integer.parseInt(props.getProperty(PROPERTY_XMAS_FLICKERTYPE+index, "4"))); + setUpdateFPS(Integer.parseInt(props.getProperty(PROPERTY_XMAS_UPDATEFPS+index, "2"))); + setWithSpaceEnabled(Boolean.parseBoolean(props.getProperty(PROPERTY_XMAS_WITHSPACE+index, "FALSE"))); + setXmasEnabled(Boolean.parseBoolean(props.getProperty(PROPERTY_XMAS_ENABLED+index, "FALSE"))); + } + public void writeProperties(final Properties props, final int forScreen) + { + final String index = '.'+Integer.toString(forScreen); + props.setProperty(PROPERTY_XMAS_ENABLED+index, Boolean.toString(isXmasEnabled())); + props.setProperty(PROPERTY_XMAS_WITHSPACE+index, Boolean.toString(isWithSpaceEnabled())); + props.setProperty(PROPERTY_XMAS_FLICKERTYPE+index, Integer.toString(getFlickerType())); + props.setProperty(PROPERTY_XMAS_UPDATEFPS+index, Integer.toString(getUpdateFPS())); + } + public void startThread() + { + getXmasDecorationPanel().startThread(); + } + public void stopThread() + { + getXmasDecorationPanel().stopThread(); + } +} diff --git a/source/de/quippy/javamod/main/gui/components/MeterPanelBase.java b/source/de/quippy/javamod/main/gui/components/MeterPanelBase.java index 19e76e0..c486058 100644 --- a/source/de/quippy/javamod/main/gui/components/MeterPanelBase.java +++ b/source/de/quippy/javamod/main/gui/components/MeterPanelBase.java @@ -25,6 +25,7 @@ import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.Insets; +import java.awt.Transparency; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; @@ -40,10 +41,10 @@ public abstract class MeterPanelBase extends ThreadUpdatePanel { private static final long serialVersionUID = -7284099301353768209L; - private volatile int myTop; - private volatile int myLeft; - private volatile int myWidth; - private volatile int myHeight; + protected volatile int myTop; + protected volatile int myLeft; + protected volatile int myWidth; + protected volatile int myHeight; private Image imageBuffer; /** @@ -86,12 +87,12 @@ protected synchronized void internalComponentWasResized() if (myWidth>0 && myHeight>0) componentWasResized(0, 0, myWidth, myHeight); } - protected synchronized Image getDoubleBuffer() + protected synchronized Image getDoubleBuffer(final int myWidth, final int myHeight) { if (imageBuffer==null && myWidth>0 && myHeight>0) { GraphicsConfiguration graConf = getGraphicsConfiguration(); - if (graConf!=null) imageBuffer = graConf.createCompatibleImage(myWidth, myHeight); + if (graConf!=null) imageBuffer = graConf.createCompatibleImage(myWidth, myHeight, Transparency.OPAQUE); } return imageBuffer; } @@ -100,13 +101,13 @@ protected synchronized Image getDoubleBuffer() */ protected synchronized void doThreadUpdate() { - Image buffer = getDoubleBuffer(); + Image buffer = getDoubleBuffer(myWidth, myHeight); if (buffer!=null) { try { drawMeter(buffer.getGraphics(), 0, 0, myWidth, myHeight); - repaint(); + repaint(myTop, myLeft, myWidth, myHeight); } catch (Exception ex) { @@ -122,7 +123,10 @@ protected synchronized void doThreadUpdate() public void paintComponent(Graphics g) { super.paintComponent(g); - Image buffer = getDoubleBuffer(); +// Graphics2D g2d = (Graphics2D) g; +// g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); +// g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); + Image buffer = getDoubleBuffer(myWidth, myHeight); if (buffer!=null) g.drawImage(buffer, myLeft, myTop, null); } /** diff --git a/source/de/quippy/javamod/main/gui/components/ThreadUpdatePanel.java b/source/de/quippy/javamod/main/gui/components/ThreadUpdatePanel.java index 657a83f..c324f27 100644 --- a/source/de/quippy/javamod/main/gui/components/ThreadUpdatePanel.java +++ b/source/de/quippy/javamod/main/gui/components/ThreadUpdatePanel.java @@ -21,7 +21,7 @@ */ package de.quippy.javamod.main.gui.components; -import javax.swing.JPanel; +import javax.swing.JComponent; import de.quippy.javamod.system.Log; @@ -29,30 +29,30 @@ * @author Daniel Becker * @since 09.09.2009 */ -public abstract class ThreadUpdatePanel extends JPanel +public abstract class ThreadUpdatePanel extends JComponent { private static final long serialVersionUID = 499420014207584726L; - private int desiredFPS; - + protected int desiredFPS; + private volatile boolean threadRunning; private volatile int pause; // 0:nothing, 1:request, 2:in Pause private final MeterUpdateThread uiUpdateThread; private static final class MeterUpdateThread extends Thread { - private long nanoWait; + private long nanoFPS; private final ThreadUpdatePanel me; public MeterUpdateThread(ThreadUpdatePanel me, final long desiredFPS) { super(); this.me = me; - nanoWait = 1000000000L / desiredFPS; + nanoFPS = 1000000000L / desiredFPS; setName("ThreadUpdatePanel::" + me.getClass().getName()); setDaemon(true); - setPriority(Thread.MAX_PRIORITY); + //setPriority(Thread.MAX_PRIORITY); } /** * Will do the Update of this... @@ -61,9 +61,17 @@ public MeterUpdateThread(ThreadUpdatePanel me, final long desiredFPS) @Override public void run() { + long additionalWait = 0; while (me.threadRunning) { final long now = System.nanoTime(); + + long stillToWait = nanoFPS - additionalWait; + if (stillToWait<=0) + stillToWait = 0L; + else + try { Thread.sleep(stillToWait/1000000L); } catch (InterruptedException ex) { /*noop*/ } + try { me.doThreadUpdate(); @@ -72,20 +80,14 @@ public void run() { Log.error(this.getName(), ex); } + if (me.pause==1) { me.pause=2; - while (me.pause==2) try { Thread.sleep(1L); } catch (InterruptedException ex) { /*noop*/ } - } - final long stillToWait = (nanoWait + now - System.nanoTime())/1000000L; - if (stillToWait>0) - { - try { Thread.sleep(stillToWait); } catch (InterruptedException ex) { /*noop*/ } - } - else - { - try { Thread.sleep(1L); } catch (InterruptedException ex) { /*noop*/ } + while (me.pause==2) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*noop*/ } } + + additionalWait = System.nanoTime() - now - stillToWait; } } } @@ -96,6 +98,7 @@ public void run() public ThreadUpdatePanel(int desiredFPS) { super(); + setDoubleBuffered(true); this.desiredFPS = desiredFPS; uiUpdateThread = new MeterUpdateThread(this, desiredFPS); } @@ -103,17 +106,21 @@ public ThreadUpdatePanel(int desiredFPS) * Will start the Thread * @since 01.01.2008 */ - protected void startThread() + public void startThread() { - threadRunning = true; - uiUpdateThread.start(); + if (!threadRunning) + { + threadRunning = true; + uiUpdateThread.start(); + } } public void pauseThread() { - if (pause==0) + if (threadRunning && pause==0) // not paused and running { - pause = 1; - while (pause==1) try { Thread.sleep(1L); } catch (InterruptedException ex) { /*NOOP */ } + pause = 1; // move into status isPaused + // wait for pause to reach status 2 (isPaused) + while (pause==1) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP */ } } } public void unPauseThread() @@ -124,9 +131,13 @@ public void unPauseThread() * Will stop this Thread * @since 01.01.2008 */ - protected void stopThread() + public void stopThread() { - threadRunning = false; + if (threadRunning) + { + threadRunning = false; + unPauseThread(); + } } /** * @since 11.09.2009 @@ -137,7 +148,7 @@ public int getDesiredFPS() return desiredFPS; } /** - * Implement the regulary updates to be done + * Implement the regular updates to be done * (i.e. Peak Meter fall downs etc.) * @since 01.01.2008 */ diff --git a/source/de/quippy/javamod/main/gui/components/XmasDecorationPanel.java b/source/de/quippy/javamod/main/gui/components/XmasDecorationPanel.java new file mode 100644 index 0000000..11afc54 --- /dev/null +++ b/source/de/quippy/javamod/main/gui/components/XmasDecorationPanel.java @@ -0,0 +1,293 @@ +/* + * @(#) XmasDecorationPanel.java + * + * Created on 05.12.2023 by Daniel Becker + * + *----------------------------------------------------------------------- + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + *---------------------------------------------------------------------- + */ +package de.quippy.javamod.main.gui.components; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Transparency; +import java.util.Random; + +import javax.swing.ImageIcon; + +/** + * @author Daniel Becker + * @since 05.12.2023 + */ +public class XmasDecorationPanel extends MeterPanelBase +{ + private static final long serialVersionUID = -3507211484792572812L; + + private static final int SYNC2FPS_BITS = 16; + private static final int SYNC2FPS_FRAC = 1<0 do not draw + private boolean inDraw; + + /** + * Constructor for XmasDecorationPanel + * @param desiredFPS + */ + public XmasDecorationPanel(final int desiredFPS, final ImageIcon [] useBulbs) + { + super(desiredFPS); + + bulbs = useBulbs; + + syncToFPScounter = SYNC2FPS_FRAC; + setUpdateFPS(DEFAULT_FPS); + rand = new Random(); + dontDraw = 0; + inDraw = false; + withSpace = false; + setFlickerType(2); + + //startThread(); // will do that only when is set visible in XmasScreenConfigPanel + } + private void enterCritical() + { + dontDraw++; + while (inDraw) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP*/ } + } + private void leaveCritical() + { + dontDraw--; + } + private void createBulbIndex(final int forWidth) + { + enterCritical(); + if (bulbs!=null && bulbs[0]!=null) + { + int anz = forWidth / bulbs[0].getIconWidth(); + if (forWidth % bulbs[0].getIconWidth()!=0) anz++; + useIndex = new int[anz]; + int oldIndex = 0; + for (int i=0; i>1) : i; + if (flickerType == FLICKERTYPE_ALTERNATE && (bulbNumber%2)==0) newIndex++; + if (flickerType == FLICKERTYPE_CHASE && (bulbNumber%4)==0) newIndex++; + useIndex[i] = (oldIndex = newIndex); + } + } + } + // We should invalidate the buffer to get a fresh clean one + imageBuffer = null; + // and instantly do a redraw: + syncToFPScounter = SYNC2FPS_FRAC; + + leaveCritical(); + } + public void setFlickerType(final int newFlickerType) + { + enterCritical(); + flickerType = newFlickerType; + createBulbIndex(getWidth()); + leaveCritical(); + } + public void setUpdateFPS(final int updateFPS) + { + syncToFPSAdd = (updateFPS<0 && myHeight>0) + { + GraphicsConfiguration graConf = getGraphicsConfiguration(); + if (graConf!=null) + { + imageBuffer = graConf.createCompatibleImage(myWidth, myHeight, Transparency.TRANSLUCENT); + Graphics2D g2d = (Graphics2D)imageBuffer.getGraphics(); + g2d.setColor(new Color(0, true)); + g2d.setComposite(AlphaComposite.Clear); + g2d.fillRect(0, 0, myWidth, myHeight); + } + } + return imageBuffer; + } + private int drawBulbAt(final Graphics2D g2d, final int x, final int bulbIndex) + { + if (bulbs!=null) + { + final ImageIcon imageIcon = bulbs[bulbIndex]; + if (imageIcon!=null) + { + g2d.drawImage(imageIcon.getImage(), x, 0, null); + return imageIcon.getIconWidth(); + } + } + return 0; + } + /** + * @param g + * @param newTop + * @param newLeft + * @param newWidth + * @param newHeight + * @see de.quippy.javamod.main.gui.components.MeterPanelBase#drawMeter(java.awt.Graphics, int, int, int, int) + */ + @Override + protected void drawMeter(Graphics g, int newTop, int newLeft, int newWidth, int newHeight) + { + try + { + syncToFPScounter += syncToFPSAdd; + if (syncToFPScounter >= SYNC2FPS_FRAC) + { + syncToFPScounter &= SYNC2FPS_MASK; + if (g!=null && bulbs!=null && bulbs.length!=0 && useIndex!=null && useIndex.length!=0 && dontDraw==0) + { + inDraw = true; + Graphics2D g2d = (Graphics2D)g; + int x = 0; + for (int index=0; index0) + { + switch (flickerType) + { + case FLICKERTYPE_ALL_OFF: + useIndex[index] = (isLit)?--bulbIndex:bulbIndex; + break; + case FLICKERTYPE_ALL_ON: + useIndex[index] = (isLit)?bulbIndex:++bulbIndex; + break; + case FLICKERTYPE_ALTERNATE: + case FLICKERTYPE_ALL_FLASH: //same as 2, but initially all bulbs are off - so all alternate between on/off + useIndex[index] = (isLit)?--bulbIndex:++bulbIndex; + break; + case FLICKERTYPE_CHASE: + if (isLit) + { + useIndex[index] = --bulbIndex; + x += drawBulbAt(g2d, x, bulbIndex); + index++; + if (index>=useIndex.length) x = index = 0; + if (withSpace) + { + x += bulbs[useIndex[index]].getIconWidth(); + index++; + if (index>=useIndex.length) + { + index = 0; + x += bulbs[useIndex[index++]].getIconWidth(); + } + } + bulbIndex = useIndex[index]; + if ((bulbIndex%2)!=0) useIndex[index] = ++bulbIndex; + if ((!withSpace && index==0) || (withSpace && index==1)) + { + drawBulbAt(g2d, x, bulbIndex); + index = useIndex.length; + } + } + break; //?? + case FLICKERTYPE_RANDOM: + if (rand.nextBoolean()) + useIndex[index] = (isLit)?--bulbIndex:++bulbIndex; + break; + case FLICKERTYPE_SOME: + if (rand.nextInt(100)<10) + useIndex[index] = (isLit)?--bulbIndex:++bulbIndex; + break; + case FLICKERTYPE_SOME_FLICKER: + if (!isLit && rand.nextInt(100)<10) bulbIndex++; + break; + default: + break; + } + } + } + x += drawBulbAt(g2d, x, bulbIndex); + } + } + } + } + finally + { + inDraw = false; + } + } + /** + * @param newTop + * @param newLeft + * @param newWidth + * @param newHeight + * @see de.quippy.javamod.main.gui.components.MeterPanelBase#componentWasResized(int, int, int, int) + */ + @Override + protected void componentWasResized(int newTop, int newLeft, int newWidth, int newHeight) + { + createBulbIndex(newWidth); + } +} diff --git a/source/de/quippy/javamod/main/gui/playlist/PlayListGUI.java b/source/de/quippy/javamod/main/gui/playlist/PlayListGUI.java index ccf8856..841db57 100644 --- a/source/de/quippy/javamod/main/gui/playlist/PlayListGUI.java +++ b/source/de/quippy/javamod/main/gui/playlist/PlayListGUI.java @@ -454,7 +454,7 @@ public void mousePressed(MouseEvent e) if (e.isConsumed() || playList==null) return; lastClickedEntry = null; - int index = getSelectedIndexFromPoint(e.getPoint(), false); + final int index = getSelectedIndexFromPoint(e.getPoint(), false); if (index!=-1) { PlayListEntry entry = playList.getEntry(index); @@ -498,7 +498,7 @@ public void mouseClicked(MouseEvent e) { if (e.isConsumed() || playList==null) return; - int index = getSelectedIndexFromPoint(e.getPoint(), false); + final int index = getSelectedIndexFromPoint(e.getPoint(), false); if (index!=-1) { if (SwingUtilities.isLeftMouseButton(e)) @@ -534,9 +534,9 @@ private JPopupMenu getPopup() playListPopUp.add(getPopUpEntryRefreshEntry()); playListPopUp.add(getPopUpEntryEditEntry()); } - boolean noEmptyList = (playList!=null && playList.size()>0); + final boolean noEmptyList = (playList!=null && playList.size()>0); PlayListEntry [] selectedEntries = (noEmptyList)?playList.getSelectedEntries():null; - boolean elementSpecificEntriesEnabled = (noEmptyList && selectedEntries!=null); + final boolean elementSpecificEntriesEnabled = (noEmptyList && selectedEntries!=null); getPopUpEntryDeleteFromList().setEnabled(elementSpecificEntriesEnabled); getPopUpEntryRefreshEntry().setEnabled(elementSpecificEntriesEnabled); getPopUpEntryEditEntry().setEnabled(elementSpecificEntriesEnabled && selectedEntries!=null && selectedEntries.length==1); diff --git a/source/de/quippy/javamod/main/gui/ressources/lightbulbs/0.gif b/source/de/quippy/javamod/main/gui/ressources/lightbulbs/0.gif new file mode 100644 index 0000000000000000000000000000000000000000..1c240084da2a9cf97a6e58f51f6a94ca4214d512 GIT binary patch literal 883 zcmZ?wbhEHbRA5kG_|DA0(7^Ej|9=Kr0!FamdS?@kUMOcM*MnNc$PmcDP+roK{p$e( z1BU^U16F{=kpw`@V>;uGp3_yE--vGu;Hb|I(0qlcoU?$wXU>*a5 z1e9j@oxtD#Q~!GdgEo-O&XE1bgMo(wWG(|kDI+8E_3|%e4Pi#MS!lZtp0N11Oo#b1H)OYE=_@n zz7AjzWw-<7F*67-h_Zb-0Mz^10jT#5ME7qQhA@uo@=}|!)jNS^!?Ysk?Z!qED1O#V6`Q$TrwfnzxXBgY^24GRu7bMSM;>@Zk(xP^yNB<05kMb{4T|E^O! z43duaNwemh`BC`DiBZXR+7=Fl)WcInSr@5r3NQ4TYHFBw=4Amx<9rA94=yi0r#CLP zZ{^dC5YcF4Vws}%_qvEi$V%tcR=!rDufx_@);iriRk|`_Q|e|rSLv;*1Ggk(i^={j s)w;Uf?{V8v=_`7U>#Hi6zMVGFe|V^t|G)3*8CegGO;G;L%fVm`0LZ(wP5=M^ literal 0 HcmV?d00001 diff --git a/source/de/quippy/javamod/main/gui/ressources/lightbulbs/10.gif b/source/de/quippy/javamod/main/gui/ressources/lightbulbs/10.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9d1b45b6d2ea62f6919bed0b7c6b15260d96120 GIT binary patch literal 970 zcmZ?wbhEHbRA5kG_|DA0(7^Ej|9^)63_t)R4jecDVo?<^f=$yqn{f0(IYYS~)NDqE zKn8~Ll9udW4;UCY43KPG0TxFR05Ol107YSX(c}g(R|M$l%Id3!CxG2}7OP8BV4`Ug z7?>GuLV5BG8bIFFLqNT04M4G*3}D^AWf;OZvdc?t%2w|Lnhn#6ptl=FuDamJdQbFF%ZE7#4$h|#{jhV_YI(2Hb|I(0qldT zU?$wXU>*a51e9j@oxtD#Q~!GdgCdYE$dLWVgMo(wWG(|kDI+8E_3|%e46G?^M;NXi0jl`3gyA|zc3C+~_Menp=Q(5;9Lg*7j(f^0{$$|< zrFij1h6M+kIrzC^b{H%?+`_{slJet&qHBlvf7dA<21!Tzq*-&$ z{3v|n#HeIDZ3~A&>fx!Ptcz4Qg%|ovH8spT^Rj@UalQll2bUM0(;FAtxAN&mh-fr2 zu}snXdtF2$WTo?JD_^V7*I{ccYn|?%DqR_|DRr}*tMt~@fm;%?#bke%YF*v#_qgq- k^c6kF^;MNj-%gw8KRi^+|KE4@jI0O8CMf^r20#*tlKYE!m)C(vw|Rs_A>*l2>>;sfOh z9NE7WCR8G;negsFLb(E1DJwAE8yFZ42!MF(GGH+f!34x{K%Bq;wDCa$8p) z&}|U$Y_Lr*a~kwy7>dd($`y-%F8jm5Ai|N&k^Kkg6b3#99tH;1!f!yMilzf~D}qf$ zA@1@sh%>k|xZf@O#>3#iTEcdO;pz#Xia$#ju5)CUm9u33N!fLtLx#bjyh87|r@Z1% z7ET6W^49^G0?HE%9LpIPIsUkBSa7hJgP$vAhrzYR9E1zzJ zh(;q5%M`u8*F`i!Rywb?^0f+m9k#}@*6Hr4(v=aLQa9VVN^e~qxFsQ5O!jxF*46EP nkK2w)U(s`1UscKU?X-#h!$YV#G literal 0 HcmV?d00001 diff --git a/source/de/quippy/javamod/main/gui/ressources/lightbulbs/12.gif b/source/de/quippy/javamod/main/gui/ressources/lightbulbs/12.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff649a75a90081e6c3a04b330bb9c9d28a8e588a GIT binary patch literal 970 zcmZ?wbhEHbRA5kG_|DA0(7^Ej|9^)63_x(;zyT0NZNLaNQ15KQ(F^4a<$6%#85sf@ z7|KgpvVT2bVBj!7vUCMl97zDgJXQh}h3Q3;!{9P8{P4fQaH71K;rbn*r2htnnDS<} z@7CX~6BroSFqGpIKsG1)*Ag{TjvM8r<<0(gUhe?wVFHps4CdWoI13U}01+UN{p(L< z0f$I=WqD=w^+!NI0RdPAn1xL6f;m8Q_$wH8Ffak5gNgrybqvD^w(mgq1N9=C|67J3 zj3c|e)TV6pPGE>2n*(8QH#V9exA;K00!Q|5g$b3&Y9_opkWj7wR>lg9_Xc2$3xIeW zGr(dX0_39vAWmWc+WY$kP%azD0|KxQu7jB=U=l${z?i=i7#v{ge{W!r1G42Avj2E6 z@Nj_4Wnd^}WMsZx{-vxO4t}nf9R>>z zx9~8Er2P1x=-MIv-*t+ILDJDaY1W)GKMEf?F)Gmn6S;e|d^O%3zT zyex2NnD4;;!R5tg^~S~at$ex>A{h)!j8pXfUKh~_S?Rpm%GWCNb=VrqTBp0GN>@f~ zO5JSdD!p}e;Fg4JG1=dxT35IGJ#ITHeMQf4eN`pXx6>y24-eJy|My)zBkRGj3Ch2D HIT)+~w|d#J literal 0 HcmV?d00001 diff --git a/source/de/quippy/javamod/main/gui/ressources/lightbulbs/13.gif b/source/de/quippy/javamod/main/gui/ressources/lightbulbs/13.gif new file mode 100644 index 0000000000000000000000000000000000000000..7821e4df752bd12f58f04d64817616b3c80d8225 GIT binary patch literal 970 zcmb_bUr19?82{br)-k3FS{bNyR}m7m?2nMHKg+TyWJ4(N!G|SE(TPxT9#;sHSws)A z2dy50GKG=_Nhw-Sw`?Y*)I%~K6s%qfA*8~Y_r^N+*y5J-)(7X~_x;ZI{l4$qbFQcK z=-z@;GGxS4fFKfy1QOsD3_?*99sO66gqm~Q7k$IPoWHaslmo1>jV{grB+tn7Z&_%qLV$YU*GRgcb@2aGx4&x()9BF)V2JqReP^oS_B z7p9-c$5%CYUv-l2QNcr;ASQ6l67$=yOCr?=cQRk?Lk`C_P^|=3qU!>FNlJ;aZ%s^} z?P@!pZHcF%Q&K1B%tixiW{w6vnMPnIlu(V2f(%#zbNxJ*YPim;9YXaFH*G^EJn&4{ z&s*U(-?Ti(M3iS}J%|z7#8RnN^W-(jhMP4zUzBced{0dSfBxHa75$$8xeJMCp1#{p zL&UbSYACO3xXmirYZm4l#aA*D#T_Mi)zS7W^SQBw`u9cB#{Jj&iCjC}xyF2FbK2^z zW1aas&yRhoL+dT~in${nzn*UGK6oi(d!;?M)s))d{1LO~p6ERsDJ&~IIa_hRprvT~ zrN6iGVeO*>#aRQ9@_rv(o1^--P7EIZa5lo^SW(Kahs|bl&_D4w9AG2%fe@6rkRfgDrOc& zWQ~a#r>|v@*GxK|I1Hx-WM4n1b zfH+YtpI-2NwQ0Uag$&3OL?!h~{0-}qRP&%HnXe7P&UqH7UW#-gd;y=Lq(s@*W+r;O z+QoZY)~Vbn>C@)4qmi{RM@&Z#4o}u?6N@z1nrMmaY8)8QhYjM6T+vND3n#R9;><}*Ep8&Z7h3M|VTh9W- zy1Hg0uXnT~U9oxNi;j}c>_ka-XD%jlyWT%(Am*_WpeRf)n%p4fiU3_*S^eeo0tN;)28Od(U77+D zeI39c!*B=6V`LCukYW3B0I2u115ocBi090$Y+3_yE--(X|l$OZ{B zFo1pV128HS?rigLvwpv(SnFoYR9 zE1zzJh(;q5%M`u8*F`i!Rywb?^0f+m9k#}@*6Hr4(v=aLQa9VVN^e~qxFsQ5O!jxF r*46EPkK2w)U(s`1UscKU?X-#h!$YYYHd;fmpm?Z!qEd$S^pRSLhx0 zlvn)8!pQ(k{yHF2KzV|JV>tsO#~=3%3l27O@N>oNFj#oFg@;ij<;Mp_*ADUju2Vb= zl8*LCv*w)nQTWJ-QOS1N77m5f!&60B7pZUxFZ7veYM6KCWdTFudSjAv>8+~+wbc&L{Dzwhc9Sr3j)Q2x!!!C(ylpMkQv literal 0 HcmV?d00001 diff --git a/source/de/quippy/javamod/main/gui/ressources/lightbulbs/4.gif b/source/de/quippy/javamod/main/gui/ressources/lightbulbs/4.gif new file mode 100644 index 0000000000000000000000000000000000000000..52502100ee299b9fb5f063453b892dac4024fe99 GIT binary patch literal 970 zcmZ?wbhEHbRA5kG_|DA0(7^Ej|9^)63?T6T|A7Msz$|JKj9|m`&L$kaP|i@U2Q`|J zA&`Ngyrd=j*8>Iy4g(|$SAfNl1VGGVB|uS_UNpHu%oPE;y0ZGqksS;SYzz!%vAQ$` zCi*&nft%qDl*hy%z`)J+=1H%CU5RYR9SPVok0dX79v z%)kKl!51(S?p`pDfk6UFGyG0qaDb`*y@7!R$mU|m{^P;G!vQjvfuWR46HnCN7%lc0jl`3gyA|zc3C+~_Menp=Q(5;9Lg*7 zj(f^0{$$|qNoVs;oTJlw*=D3bEygQ9DP_e(g`v;d7pVJ!` z+qd%RMu=!MGO(AQyWENh+ao+@1#u_<-4ovZZL)qz_Qvc+V7 tmug+z?)SLusPq**$Msc}Oy5qM=s!GE%m3eZ^^B|s$0jKM=H+0p1^}jjwo(89 literal 0 HcmV?d00001 diff --git a/source/de/quippy/javamod/main/gui/ressources/lightbulbs/5.gif b/source/de/quippy/javamod/main/gui/ressources/lightbulbs/5.gif new file mode 100644 index 0000000000000000000000000000000000000000..dd8d294e2d883bdeea691d60b4667c1e92ffc858 GIT binary patch literal 965 zcmZ?wbhEHbRA5kG_|DA0(7^Ej|9^)63_x(;zyT0NZNLaNQ15KQ(F^4a<$6%#85sf@ z7|KgpvVT2bVBj!7vUCMl97zDgJXQh}h3Q3;8^l}@psOpZznnP1z`(}9a2BgeQ(&U6 z0~kaZ?m&5r3<3b(Qe{ac11j3c|e)TV6pPN3N^tq6L%vC#y%#Rtk2 zII@2$OsGUwGvVEVgmMM2QdVHRHvnT?0K{W|0Tu%hOh6n5#0d;Qdw<_xW8laJ2{SN& zeeea$gu55aV_=Yg(hR>77#v{ge{W!52C_LBvj2E6@Nj_4Wnd^}WMsZx{-vxOe~j_k5>mh3+%yUugSFgTP~=pFZz zSNzGs$pB3LIv`U(d4hps5d$N~ANLIl4mNY}bH(g1Sa`UFhfyTu#|K5%4)Oo4Q#=fk zj`m5j=A8La_{fP-$#&Wn4u#aiQ$<-9sc;G}^qFdEn0Mx7!GU9pHiExIJQl2QSm4Ob zm+Ha5aB0c^X?i)oOjcZ(AF$qS&8*AmmnX(#SINFK(Qa5DF`3Wxw1Li=b@hvd_W;DC*mRQd z3PN_DyO6E){*~Jh@{qS>AV~v|&SKIQfjRWExoj@Bq4r;dQb#O|?=_PQb<=el=f_^9 zeo+tSiAdeYJ>e(#MwB}1{^LUjgFD7zR3Kte2>O&Y!7nj86~ajG=^=ArUz zgF`smIxn)FDms3n9-P!m4Nja)BA_KA5hWZ2>Ol{ncH~jYc?Y`=MyK3-uZotUC=qs%ii~|9!HG{7(Rx0FFqONGKj4 zn%YY68xi+RU~liaQow;vMWN@94cdUSV9!^oLo z^MRhlPrdNs9$&qB>SM#6zOkm8_01QwO?{!$cX@NI`P%CT*6A+wlxuS7{>7(j((I$D z4$dAOOm!Y^?wG!sXe*^Xxi`^s?_N%XJ^SO~&eB@Rr|YrD1Dn2X4>d+t76w#29Qz5z C8QcH> literal 0 HcmV?d00001 diff --git a/source/de/quippy/javamod/main/gui/ressources/lightbulbs/7.gif b/source/de/quippy/javamod/main/gui/ressources/lightbulbs/7.gif new file mode 100644 index 0000000000000000000000000000000000000000..849a03973c2c9d99a6afde63eb3f9b98a0e409b8 GIT binary patch literal 970 zcmZ?wbhEHbRA5kG_|DA0(7^Ej|9^)63_#Gp&~V_u0T7F-fDvq(-r0ns7s?sR^`K@m zG6XU(l$W$*|9Zf{z+r%7;|j1ik^qQ#tOO_u(~BmD!DV8&;lG1Hqr92n>LCnC5(JRV z$^NxO&6HzDd1-mG|D9J0z@{((NgxLE?l7DMi3u<;EC5n>UST{1(=0Qu!1>2a|B;7++<(^MhBCS1%n!c27?sP{Xo6Q=Kq#q2;;~uFSRLKy%QKB z$mT%U+l`GT$SpoluE3G~TVX;avYH9+4kVN-fR(X=BAbEX0MNO>&@TXsfe4U~Vt_b~ z0ch{<8$h{ikT3%S*aug^%oH$*AS7VS-w6y3F!jGTFfanyq72!8JQ#R5K;|+qlrl0h zUoZbsRt|DoS0B)A5bpX`H zgF|_R-f>TP#h)yk48Y{C12P4aCm1-E16}^deZzu-%^dt(F*^(v9&X`b6iNBcA}t x*L(i`AtmFws{V z7+Sm1K0;w zfsE`w9zapB7?hBJaegN-IKb5Z-oT&^WOIYn^KgL7Wnd^}WMsZx{-vxO>m1o-e$RWf}$ZKD71P%Zy|-_pX`HgF|_R-f>TP#h)yk48Y{C z12P4aCm1-EGca=eao@1uU^53lSIiEBg@;>s7)4Tkd{A`l5dZHw#ls-!XrDA|&Y2&D zkDM5lY^QDEP)I#IRg`s+3a9WwpQ)yXd1qc0Ff`70VE^Fq;&XcAV*6G;-3SqlMkbai zdVjBrXoReEUTx)T75X}Cjb*LV-BYD2BQ~XOwsV! newEntries = new ArrayList(size()); while (!entries.isEmpty()) { diff --git a/source/de/quippy/javamod/mixer/Mixer.java b/source/de/quippy/javamod/mixer/Mixer.java index b6202c5..9c8d301 100644 --- a/source/de/quippy/javamod/mixer/Mixer.java +++ b/source/de/quippy/javamod/mixer/Mixer.java @@ -38,14 +38,15 @@ public abstract class Mixer private SoundOutputStream outputStream; private AudioProcessor audioProcessor; private AudioFormat audioFormat; - private File exportFile; - private boolean playDuringExport; private boolean keepSilent; private int sourceLineBufferSize; private float currentVolume; private float currentBalance; + protected boolean playDuringExport; + protected File exportFile; + /** * Constructor for Mixer */ diff --git a/source/de/quippy/javamod/multimedia/mod/ModConfigPanel.java b/source/de/quippy/javamod/multimedia/mod/ModConfigPanel.java index 340a7c6..a7de60b 100644 --- a/source/de/quippy/javamod/multimedia/mod/ModConfigPanel.java +++ b/source/de/quippy/javamod/multimedia/mod/ModConfigPanel.java @@ -319,7 +319,7 @@ public JCheckBox getPlayerSetUp_fadeOutLoops() { playerSetUp_fadeOutLoops = new JCheckBox(); playerSetUp_fadeOutLoops.setName("playerSetUp_fadeOutLoops"); - playerSetUp_fadeOutLoops.setText("Fade out infinit loops"); + playerSetUp_fadeOutLoops.setText("Fade out infinite loops"); playerSetUp_fadeOutLoops.setFont(Helpers.getDialogFont()); playerSetUp_fadeOutLoops.addItemListener(new ItemListener() { @@ -342,7 +342,7 @@ public JCheckBox getPlayerSetUp_ignoreLoops() { playerSetUp_ignoreLoops = new JCheckBox(); playerSetUp_ignoreLoops.setName("playerSetUp_ignoreLoops"); - playerSetUp_ignoreLoops.setText("Ignore infinit loops"); + playerSetUp_ignoreLoops.setText("Ignore infinite loops"); playerSetUp_ignoreLoops.setFont(Helpers.getDialogFont()); playerSetUp_ignoreLoops.addItemListener(new ItemListener() { diff --git a/source/de/quippy/javamod/multimedia/mod/ModContainer.java b/source/de/quippy/javamod/multimedia/mod/ModContainer.java index 3d63350..ef3c574 100644 --- a/source/de/quippy/javamod/multimedia/mod/ModContainer.java +++ b/source/de/quippy/javamod/multimedia/mod/ModContainer.java @@ -285,6 +285,8 @@ public void configurationSave(Properties props) props.setProperty(PROPERTY_PLAYER_DITHERBYPASS, Boolean.toString(configPanel.getPlayerSetUp_ByPassDither().isSelected())); } /** + * Will create a new mixer for the currently loaded mod. + * We assume, that a mod is already loaded and therefore registering a listener is valid! * @see de.quippy.javamod.multimedia.MultimediaContainer#createNewMixer() * @since: 12.10.2007 * @return @@ -294,7 +296,7 @@ public Mixer createNewMixer() { deregisterUpdateListener(); - if (currentMod==null) return null; + if (currentMod==null) return null; // you cannot get a mixer without a mod loaded. Properties props = new Properties(); configurationSave(props); @@ -335,7 +337,8 @@ private void deregisterUpdateListener() } } // always stop the update thread - if it is not there, this does no harm - modInfoPanel.getModPatternDialog().stopUpdateThread(); + ((ModInfoPanel)getInfoPanel()).getModPatternDialog().stopUpdateThread(); + ((ModInfoPanel)getInfoPanel()).getModPatternDialog().setMixer(null); } /** * @since 11.11.2023 @@ -349,9 +352,10 @@ private void registerUpdateListener() BasicModMixer mixer = currentMixer.getModMixer(); if (mixer!=null) { - mixer.registerUpdateListener(modInfoPanel.getModPatternDialog()); - modInfoPanel.getModPatternDialog().startUpdateThread(); + mixer.registerUpdateListener(((ModInfoPanel)getInfoPanel()).getModPatternDialog()); + ((ModInfoPanel)getInfoPanel()).getModPatternDialog().startUpdateThread(); } + ((ModInfoPanel)getInfoPanel()).getModPatternDialog().setMixer(mixer); } } /** diff --git a/source/de/quippy/javamod/multimedia/mod/ModInfoPanel.java b/source/de/quippy/javamod/multimedia/mod/ModInfoPanel.java index 37f337d..dc7f3aa 100644 --- a/source/de/quippy/javamod/multimedia/mod/ModInfoPanel.java +++ b/source/de/quippy/javamod/multimedia/mod/ModInfoPanel.java @@ -66,6 +66,10 @@ public class ModInfoPanel extends JPanel implements HasParentDialog private JDialog parent = null; + private int oldModPatternDialogVisibility = -1; + private int oldModSampleDialogVisibility = -1; + private int oldModInstrumentDialogVisibility = -1; + /** * Constructor for ModInfoPanel */ @@ -119,12 +123,70 @@ public void setParentDialog(JDialog parent) public void updateUI() { super.updateUI(); - // do not use "getModPatterDialog" here. When this is called, this - // panel does not have a parent container. + // do not use the getter Methods here. When this is initially called, + // this panel does not have a parent container yet. if (modPatternDialog!=null) SwingUtilities.updateComponentTreeUI(modPatternDialog); if (modSampleDialog!=null) SwingUtilities.updateComponentTreeUI(modSampleDialog); if (modInstrumentDialog!=null) SwingUtilities.updateComponentTreeUI(modInstrumentDialog); } + /** + * We want to close our possible open children dialogs + * when this panel gets removed from the ModInfoPane. + * We remember the visibility status for reset. + * @see de.quippy.javamod.multimedia.mod.ModInfoPanel#addNotify + * @see javax.swing.JComponent#removeNotify() + */ + @Override + public void removeNotify() + { + super.removeNotify(); + if (modPatternDialog != null) + { + oldModPatternDialogVisibility = (modPatternDialog.isVisible()) ? 1 : 0; + modPatternDialog.setVisible(false); + } + if (modSampleDialog != null) + { + oldModSampleDialogVisibility = (modSampleDialog.isVisible()) ? 1 : 0; + modSampleDialog.setVisible(false); + } + if (modInstrumentDialog != null) + { + oldModInstrumentDialogVisibility = (modInstrumentDialog.isVisible()) ? 1 : 0; + modInstrumentDialog.setVisible(false); + } + } + /** + * After being added to the ModInfoPane, recreate the last status of + * visibility of potential open dialogs again. + * But check also, if an old value was set. If the old value == -1 the status is not set. + * Other is like C: 0==false, !0==true + * After using the value, invalidate the setting. + * @see javax.swing.JComponent#addNotify() + */ + @Override + public void addNotify() + { + super.addNotify(); + if (modPatternDialog != null && oldModPatternDialogVisibility != -1) + { + modPatternDialog.setVisible(oldModPatternDialogVisibility != 0); + oldModPatternDialogVisibility = -1; + } + if (modSampleDialog != null && oldModSampleDialogVisibility != -1) + { + modSampleDialog.setVisible(oldModSampleDialogVisibility != 0); + oldModSampleDialogVisibility = -1; + } + if (modInstrumentDialog != null && oldModInstrumentDialogVisibility != -1) + { + modInstrumentDialog.setVisible(oldModInstrumentDialogVisibility != 0); + oldModInstrumentDialogVisibility = -1; + } + } + /** + * @since 13.10.2007 + */ private void initialize() { this.setName("ModInfoPane"); @@ -240,7 +302,7 @@ protected ModPatternDialog getModPatternDialog() { if (modPatternDialog==null) { - modPatternDialog = new ModPatternDialog(parent, false); + modPatternDialog = new ModPatternDialog(this, parent, false); modPatternDialog.setLocation(Helpers.getFrameCenteredLocation(modPatternDialog, parent)); } return modPatternDialog; @@ -249,7 +311,7 @@ protected ModSampleDialog getModSampleDialog() { if (modSampleDialog==null) { - modSampleDialog = new ModSampleDialog(parent, false); + modSampleDialog = new ModSampleDialog(this, parent, false); modSampleDialog.setLocation(Helpers.getFrameCenteredLocation(modSampleDialog, parent)); } return modSampleDialog; @@ -258,7 +320,7 @@ protected ModInstrumentDialog getModInstrumentDialog() { if (modInstrumentDialog==null) { - modInstrumentDialog = new ModInstrumentDialog(parent, false); + modInstrumentDialog = new ModInstrumentDialog(this, parent, false); modInstrumentDialog.setLocation(Helpers.getFrameCenteredLocation(modInstrumentDialog, parent)); } return modInstrumentDialog; @@ -328,6 +390,11 @@ private JTextField getModInfo_Trackername() } return modInfo_Trackername; } + public void showSample(final int sampleIndex) + { + getModSampleDialog().showSample(sampleIndex); + getModSampleDialog().setVisible(true); + } public void fillInfoPanelWith(final Module currentMod) { if (currentMod==null) @@ -360,7 +427,7 @@ public void fillInfoPanelWith(final Module currentMod) // get destroyed (and will never be visible anyways...) if (parent!=null) { - if (currentMod.getPatternContainer()!=null) getModPatternDialog().fillWithPatternArray(currentMod.getSongLength(), currentMod.getArrangement(), currentMod.getPatternContainer().getPattern()); + if (currentMod.getPatternContainer()!=null) getModPatternDialog().fillWithPatternArray(currentMod.getSongLength(), currentMod.getArrangement(), currentMod.getPatternContainer()); if (currentMod.getInstrumentContainer()!=null) { getModSampleDialog().fillWithSamples(currentMod.getInstrumentContainer().getSamples()); diff --git a/source/de/quippy/javamod/multimedia/mod/ModMixer.java b/source/de/quippy/javamod/multimedia/mod/ModMixer.java index aeeb12c..19aa907 100644 --- a/source/de/quippy/javamod/multimedia/mod/ModMixer.java +++ b/source/de/quippy/javamod/multimedia/mod/ModMixer.java @@ -457,7 +457,8 @@ public void startPlayback() openAudioDevice(); if (!isInitialized()) return; - modMixer.setFireUpdates(true); + // If we do export to wave and do not want to play during that, do not fire any updates + if (exportFile==null || playDuringExport) modMixer.setFireUpdates(true); int count; do diff --git a/source/de/quippy/javamod/multimedia/mod/gui/ModInstrumentDialog.java b/source/de/quippy/javamod/multimedia/mod/gui/ModInstrumentDialog.java index 94df5cb..e0693cc 100644 --- a/source/de/quippy/javamod/multimedia/mod/gui/ModInstrumentDialog.java +++ b/source/de/quippy/javamod/multimedia/mod/gui/ModInstrumentDialog.java @@ -25,6 +25,8 @@ import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.GridBagLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.ArrayList; import javax.swing.JDialog; @@ -33,16 +35,20 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; +import javax.swing.JSpinner.DefaultEditor; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SpinnerListModel; +import javax.swing.SwingUtilities; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.swing.text.Caret; import de.quippy.javamod.main.gui.tools.FixedStateCheckBox; import de.quippy.javamod.multimedia.mod.ModConstants; +import de.quippy.javamod.multimedia.mod.ModInfoPanel; import de.quippy.javamod.multimedia.mod.gui.EnvelopePanel.EnvelopeType; import de.quippy.javamod.multimedia.mod.loader.instrument.Instrument; import de.quippy.javamod.system.Helpers; @@ -55,6 +61,8 @@ public class ModInstrumentDialog extends JDialog { private static final long serialVersionUID = -5890906666611603247L; + private static final int SAMPLE_MAP_LINE_LENGTH = 15; + private JLabel labelSelectInstrument = null; private JSpinner selectInstrument = null; @@ -112,14 +120,17 @@ public class ModInstrumentDialog extends JDialog private EnvelopePanel pitchEnvelopePanel = null; private Instrument [] instruments = null; + private ArrayList spinnerModelData = null; + private ModInfoPanel myModInfoPanel; /** * Constructor for ModPatternDialog */ - public ModInstrumentDialog() + public ModInstrumentDialog(ModInfoPanel infoPanel) { super(); + myModInfoPanel = infoPanel; initialize(); } /** @@ -127,9 +138,10 @@ public ModInstrumentDialog() * @param owner * @param modal */ - public ModInstrumentDialog(JFrame owner, boolean modal) + public ModInstrumentDialog(ModInfoPanel infoPanel, JFrame owner, boolean modal) { super(owner, modal); + myModInfoPanel = infoPanel; initialize(); } /** @@ -137,9 +149,10 @@ public ModInstrumentDialog(JFrame owner, boolean modal) * @param owner * @param modal */ - public ModInstrumentDialog(JDialog owner, boolean modal) + public ModInstrumentDialog(ModInfoPanel infoPanel, JDialog owner, boolean modal) { super(owner, modal); + myModInfoPanel = infoPanel; initialize(); } private void initialize() @@ -174,6 +187,8 @@ public void windowClosing(java.awt.event.WindowEvent e) setPreferredSize(getSize()); pack(); setLocation(Helpers.getFrameCenteredLocation(this, getParent())); + + fillWithInstrument(null); } public void doClose() { @@ -191,6 +206,10 @@ private JLabel getLabelSelectInstrument() } return labelSelectInstrument; } + private int getCurrentInstrument() + { + return Integer.parseInt((String)getSelectInstrument().getModel().getValue(), 16) - 1; + } private JSpinner getSelectInstrument() { if (selectInstrument==null) @@ -213,8 +232,7 @@ public void stateChanged(ChangeEvent e) { if (instruments!=null) { - Integer sampleIndex = (Integer)getSelectInstrument().getModel().getValue(); - fillWithInstrument(instruments[sampleIndex.intValue()-1]); + fillWithInstrument(instruments[getCurrentInstrument()]); } } }); @@ -784,7 +802,47 @@ private JTextArea getSampleMap() if (sampleMap==null) { sampleMap = new JTextArea(); + sampleMap.setName("SampleMap"); + sampleMap.setEditable(false); // no editing sampleMap.setFont(Helpers.getTextAreaFont()); + final Caret caret = sampleMap.getCaret(); + caret.setVisible(false); // no cursor + caret.setSelectionVisible(true); // but selection is visible + // As in some cases, when the textbox gains focus, the cursor appears nevertheless, we just make it invisible... + sampleMap.setCaretColor(sampleMap.getBackground()); + sampleMap.addMouseListener(new MouseAdapter() + { + public void mouseClicked(MouseEvent e) + { + if (e.isConsumed() || instruments == null) return; + + final int modelPos = getSampleMap().viewToModel2D(e.getPoint()); + final int row = modelPos / SAMPLE_MAP_LINE_LENGTH; // 15 characters per line incl. LF + + // show a marker at what we selected. + final int startPoint = row * SAMPLE_MAP_LINE_LENGTH; + final int endPoint = startPoint + SAMPLE_MAP_LINE_LENGTH; + try + { + getSampleMap().setCaretPosition(startPoint); + getSampleMap().moveCaretPosition(endPoint); + + if (SwingUtilities.isLeftMouseButton(e)) + { + if (e.getClickCount()>1) + { + // now get the sample and force sample dialog to open and show that: + final int sampleIndex = getSampleIndex(getCurrentInstrument(), row); + if (sampleIndex!=-1) myModInfoPanel.showSample(sampleIndex); + } + } + } + catch (IllegalArgumentException ex) + { + // Ignore it... + } + } + }); } return sampleMap; } @@ -889,13 +947,30 @@ private String getSampleMapString(int [] noteIndex, int [] sampleIndex) else { sb.append(ModConstants.getNoteNameForIndex(noteIndex[i]+1)).append(" | "); - sb.append(sampleIndex[i]).append('\n'); + sb.append(ModConstants.getAsHex(sampleIndex[i], 2)).append('\n'); } } return sb.toString(); } + private int getSampleIndex(final int instrumentIndex, final int row) + { + if (instruments!=null) + { + Instrument instrument = instruments[instrumentIndex]; + if (instrument!=null) + { + final int noteIndex = instrument.getNoteIndex(row); + if ((noteIndex&0x80)==0) return instrument.getSampleIndex(row); + } + } + return -1; + } private void clearInstrument() { + spinnerModelData = new ArrayList(1); + spinnerModelData.add(ModConstants.getAsHex(0, 2)); + getSelectInstrument().setModel(new SpinnerListModel(spinnerModelData)); + getInstrumentName().setText(Helpers.EMPTY_STING); getFileName().setText(Helpers.EMPTY_STING); @@ -928,39 +1003,43 @@ private void clearInstrument() getPanningEnvelopePanel().setEnvelope(null, EnvelopeType.panning); getPitchEnvelopePanel().setEnvelope(null, EnvelopeType.pitch); } - private void fillWithInstrument(Instrument instrument) + private void fillWithInstrument(Instrument newInstrument) { - if (instrument==null) + if (newInstrument==null) { clearInstrument(); } else { - getInstrumentName().setText(instrument.name); - getFileName().setText(instrument.dosFileName); + spinnerModelData = new ArrayList(instruments.length); + for (int i=0; i list = new ArrayList(instruments.length); - for (int i=0; i buffer; + private static final int INITIAL_SIZE = 0x1000; // 64 channel with 750ms sound buffer needs a push buffer of approx. 0xF00 size. +// private static final int GROW_BY_SIZE = 0x100; + private CircularBuffer buffer; + private volatile boolean running; private volatile boolean hasStopped; - private long additionalWait; - private long lastTimeCode; + private volatile boolean updating; + private volatile boolean paused; + private volatile boolean isPaused; + private volatile boolean drain; public SongFollower() { super(); - buffer = new CircularBuffer(128); + buffer = new CircularBuffer(INITIAL_SIZE); //64 Channel mod has already possibly 64 + 1 Events per row - so give us some room! running = true; hasStopped = false; - additionalWait = 0; - lastTimeCode = 0; + updating = false; + paused = isPaused = false; + drain = false; setName("InformerThread"); setDaemon(true); // try { this.setPriority(Thread.MAX_PRIORITY); } catch (SecurityException ex) { /*NOOP*/ } @@ -100,9 +217,35 @@ public SongFollower() * @since 13.11.2023 * @param information */ - public void push(final ModUpdateListener.InformationObject information) + public void push(final TimedInformation information) + { + while (drain) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP*/ } + if (running) + { + //if (buffer.isFull()) buffer.growBy(GROW_BY_SIZE); // we do not want to grow as that is not thread safe. If events cannot be pushed, forget them! + buffer.push(information); + } + } + /** + * Invalidate all events in the queue + * @since 24.11.2023 + */ + public void flush() { - buffer.push(information); + buffer.flush(); + while (updating) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP*/ } + } + /** + * Will halt adding of new events and deliver / drain all remains + * in buffer. Method blocks, till all left over events are gone. + * This will also block the push method, till all is delivered. + * @since 29.11.2023 + */ + public void drain() + { + drain = true; + while (!buffer.isEmpty()) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP*/ } + drain = false; } /** * This will stop the thread gracefully and halt it. After this call @@ -112,44 +255,25 @@ public void push(final ModUpdateListener.InformationObject information) public void stopMe() { running = false; - buffer.flush(); + flush(); while (!hasStopped) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP*/ } } /** - * Do everything that is needed to display a new pattern. - * @since 13.11.2023 - * @param information + * Will pause/unpause the thread + * @since 28.11.2023 + * @param isPaused */ - private void displayPattern(final ModUpdateListener.InformationObject information) + public void pause(final boolean doPause) { - if (ModPatternDialog.this.isVisible() && information!=null) - { - try - { - final int index = (int)((information.position >> 48)&0xFFFF); - if (index!=currentIndex && index> 16)&0xFFFF); - final int patternIndex = arrangement[index]; - Pattern pattern = patterns[patternIndex]; - if (pattern!=null) - { - int lineLength = pattern.getPatternRowCharacterLength() + 1; - int startIndex = row * lineLength; - getTextView_PatternData().setCaretPosition(startIndex); - getTextView_PatternData().moveCaretPosition(startIndex + lineLength); - } - } - catch (Throwable ex) - { - //If anything happens here, it stays here. - } - } + paused = doPause; + while (paused!=isPaused) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP*/ } } public void run() { + long additionalWait = 0; + long lastTimeCode = 0; hasStopped=false; + while (running) { // wait for the first event to appear @@ -160,23 +284,39 @@ public void run() { final long startNanoTime = System.nanoTime(); - ModUpdateListener.InformationObject information = buffer.pop(); - + TimedInformation information = buffer.peek(0); long nanoWait = ((information.timeCode - lastTimeCode) * 1000000L) - additionalWait; lastTimeCode = information.timeCode; - - if (nanoWait > 0) // are we far behind?! - try { Thread.sleep(nanoWait/1000000L); } catch (InterruptedException ex) { /*NOOP*/ } + if (nanoWait<=0) + nanoWait = 0L; else + try { Thread.sleep(nanoWait/1000000L); } catch (InterruptedException ex) { /*NOOP*/ } + + updating = true; + while (!buffer.isEmpty() && ((TimedInformation)buffer.peek(0)).timeCode <= lastTimeCode) { - nanoWait = 0; - try { Thread.sleep(1L); } catch (InterruptedException ex) { /*NOOP*/ } + information = buffer.pop(); + // if dialog is not visible, do not make any updates. + if (ModPatternDialog.this.isVisible()) + { + if (information instanceof PositionInformation) + displayPattern((PositionInformation)information); + else + if (information instanceof PeekInformation) + updateVolume(((PeekInformation)information).channel, ((PeekInformation)information).actPeekLeft, ((PeekInformation)information).actPeekRight); + } } - - displayPattern(information); + updating = false; // if this was the last event in the queue, wait for the next one - typically this is a pattern delay... while (buffer.isEmpty() && running) try { Thread.sleep(1L); } catch (InterruptedException ex) { /*NOOP*/ } + + if (paused) // if we should pause updates, wait here... + { + isPaused = true; + while (paused && running) try { Thread.sleep(10L); } catch (InterruptedException ex) { /*NOOP*/ } + isPaused = false; + } if (!running) break; // if we got stopped meanwhile, let's drop out... additionalWait = System.nanoTime() - startNanoTime - nanoWait; @@ -189,53 +329,58 @@ public void run() // The UpdateListener Thread - to decouple whoever wants to get informed private SongFollower songFollower; - private JScrollPane scrollPane_ArrangementData = null; - private JPanel arrangementPanel = null; - private JPanel fixedHightPanel = null; - private JLabel labelArrangement = null; + private JPanel topArrangementPanel = null; private JButton nextPatternButton = null; private JButton prevPatternButton = null; - private JScrollPane scrollPane_PatternData = null; -// private JTextPane textArea_PatternData= null; - private JTextArea textArea_PatternData= null; - private JToggleButton [] buttonArrangement; + private JCheckBox followSongCheckBox = null; + private JPanel arrangementPanel = null; + private JScrollPane scrollPane_ArrangementData = null; private ButtonGroup buttonGroup = null; + private JToggleButton [] buttonArrangement; + + private JTextArea textArea_PatternData= null; + private JScrollPane scrollPane_PatternData = null; - private int [] arrangement; - private Pattern [] patterns; + private JPanel channelHeadlinePanel = null; + private JButton [] channelButtons = null; + private JLabel [] effectLabels = null; + private JLabel [] volEffectLabels = null; + private JPopupMenu channelPopUp = null; + private JMenuItem popUpEntrySoloChannel = null; + private JMenuItem popUpEntryMuteChannel = null; + private JMenuItem popUpEntryUnMuteAll = null; + + private JPanel rowHeadlinePanel = null; + private JLabel [] rowLabels = null; + private GridBagConstraints [] rowLabelConstraints = null; + private static final int START_ROWLABELS_AMOUNT = 0xFF; // let us create 256 row labels in advance. If that is not enough, let us create more + private JPanel upperLeftCornerPanel = null; + private JLabel patternNumberLabel = null; + + private Dimension PATTERNINDEX_BUTTON = null; + private Dimension PATTERNINDEX_SIZE = null; + private Dimension PATTERNBUTTON_SIZE = null; + private Dimension CHANNELBUTTON_SIZE = null; + + private BasicModMixer currentMixer; + + private int [] arrangement = null; + private PatternContainer patternContainer = null; private int currentIndex; + private int selectedChannelNumber = -1; // Popup on which channel? + + private String peekMeterColorStrings[]; -// private static final char[] EOL_ARRAY = { '\n' }; -// private static Color NOTECOLOR = new Color(0x00, 0x33, 0xCC); -// private static Color INSTRUMENTCOLOR = new Color(0x00, 0x99, 0xCC); -// private static Color VOLUMECOLOR = new Color(0x00, 0x99, 0x33); -// private static Color EFFECTCOLOR = new Color(0xCC, 0x00, 0xCC); -// private AttributeSet foregroundAttSet; -// private AttributeSet noteAttSet; -// private AttributeSet instrumentAttSet; -// private AttributeSet volumeAttSet; -// private AttributeSet effectAttSet; -// -// private class InternalDefaultStyleDocument extends DefaultStyledDocument -// { -// private static final long serialVersionUID = 8443419464715235236L; -// -// public void processBatchUpdates(final int offs, final ArrayList batch) throws BadLocationException -// { -// ElementSpec[] inserts = new ElementSpec[batch.size()]; -// batch.toArray(inserts); -// -// super.insert(offs, inserts); -// } -// } -// private InternalDefaultStyleDocument EMPTY_DOCUMENT = null; + @SuppressWarnings("unused") + private ModInfoPanel myModInfoPanel; /** * Constructor for ModPatternDialog */ - public ModPatternDialog() + public ModPatternDialog(ModInfoPanel infoPanel) { super(); + myModInfoPanel = infoPanel; initialize(); } /** @@ -243,9 +388,10 @@ public ModPatternDialog() * @param owner * @param modal */ - public ModPatternDialog(JFrame owner, boolean modal) + public ModPatternDialog(ModInfoPanel infoPanel, JFrame owner, boolean modal) { super(owner, modal); + myModInfoPanel = infoPanel; initialize(); } /** @@ -253,17 +399,39 @@ public ModPatternDialog(JFrame owner, boolean modal) * @param owner * @param modal */ - public ModPatternDialog(JDialog owner, boolean modal) + public ModPatternDialog(ModInfoPanel infoPanel, JDialog owner, boolean modal) { super(owner, modal); + myModInfoPanel = infoPanel; initialize(); } private void initialize() { - final Container baseContentPane = getContentPane(); + // Let's first create the normal and darker color for the meters + peekMeterColorStrings = new String[16]; + for (int i=0; i<8; i++) + { + final int r = i*255/8; + final int g = 255-r; + peekMeterColorStrings[i]="#"+ModConstants.getAsHex(r, 2)+ModConstants.getAsHex(g, 2)+"00"; + peekMeterColorStrings[i+8]=PEEK_METER_BUTTON_BACKGROUND; //="#"+ModConstants.getAsHex(r>>1, 2)+ModConstants.getAsHex(g>>1, 2)+"00"; + } + + final Container baseContentPane = getContentPane(); + + final FontMetrics textAreaMetrics = baseContentPane.getFontMetrics(Helpers.getTextAreaFont()); + PATTERNBUTTON_SIZE = new Dimension(textAreaMetrics.charWidth('0') * Pattern.LINEINDEX_LENGTH, textAreaMetrics.getHeight()); + CHANNELBUTTON_SIZE = new Dimension(textAreaMetrics.charWidth('0') * Pattern.ROW_LENGTH, textAreaMetrics.getHeight()); + + final FontMetrics dialogMetrics = baseContentPane.getFontMetrics(Helpers.getDialogFont()); + PATTERNINDEX_BUTTON = new Dimension(dialogMetrics.charWidth('0') * 6, dialogMetrics.getHeight() * 2); + PATTERNINDEX_SIZE = new Dimension(dialogMetrics.charWidth('0'), dialogMetrics.getHeight() * 4); + + createRowLabels(START_ROWLABELS_AMOUNT); + baseContentPane.setLayout(new java.awt.GridBagLayout()); - baseContentPane.add(getFixedHightPanel(), Helpers.getGridBagConstraint(0, 0, 1, 0, java.awt.GridBagConstraints.HORIZONTAL, java.awt.GridBagConstraints.WEST, 1.0, 0.0)); + baseContentPane.add(getTopArrangementPanel(), Helpers.getGridBagConstraint(0, 0, 1, 0, java.awt.GridBagConstraints.HORIZONTAL, java.awt.GridBagConstraints.WEST, 1.0, 0.0)); baseContentPane.add(getScrollPane_PatternData(), Helpers.getGridBagConstraint(0, 1, 1, 0, java.awt.GridBagConstraints.BOTH, java.awt.GridBagConstraints.WEST, 1.0, 1.0)); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); @@ -284,70 +452,94 @@ public void windowClosing(java.awt.event.WindowEvent e) pack(); setLocation(Helpers.getFrameCenteredLocation(this, getParent())); } - /** - * push an event into the songFollower queue - * @param information - * @see de.quippy.javamod.multimedia.mod.gui.ModUpdateListener#getMixerInformation(de.quippy.javamod.multimedia.mod.gui.ModUpdateListener.InformationObject) - */ - public void getMixerInformation(final ModUpdateListener.InformationObject information) + private void doClose() { - if (songFollower!=null) songFollower.push(information); + setVisible(false); + dispose(); } - /** - * Stop the thread - * @since 13.11.2023 - */ - public void stopUpdateThread() + private JPanel getTopArrangementPanel() { - if (songFollower!=null) + if (topArrangementPanel==null) { - songFollower.stopMe(); - songFollower = null; + topArrangementPanel = new JPanel(); + topArrangementPanel.setLayout(new GridBagLayout()); + topArrangementPanel.add(getPrevPatternButton(), Helpers.getGridBagConstraint(0, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); + topArrangementPanel.add(getNextPatternButton(), Helpers.getGridBagConstraint(1, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); + topArrangementPanel.add(getFollowSongCheckBox(), Helpers.getGridBagConstraint(0, 1, 1, 2, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.CENTER, 0.0, 0.0)); + topArrangementPanel.add(getScrollPane_ArrangementData(),Helpers.getGridBagConstraint(2, 0, 2, 1, java.awt.GridBagConstraints.BOTH, java.awt.GridBagConstraints.WEST, 1.0, 1.0)); + topArrangementPanel.setMinimumSize(PATTERNINDEX_SIZE); } + return topArrangementPanel; } - /** - * Create and start the Thread - * @since 13.11.2023 - */ - public void startUpdateThread() - { - if (songFollower!=null) stopUpdateThread(); - songFollower = new SongFollower(); - songFollower.start(); - } - private void doClose() + private JButton getPrevPatternButton() { - setVisible(false); - dispose(); + if (prevPatternButton==null) + { + prevPatternButton = new JButton(); + prevPatternButton.setName("prevPatternButton"); + prevPatternButton.setText("<<"); + prevPatternButton.setFont(Helpers.getDialogFont()); + prevPatternButton.setToolTipText("Show previous pattern"); + prevPatternButton.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (arrangement!=null && currentIndex>0) + fillWithArrangementIndex(currentIndex-1); + } + }); + } + return prevPatternButton; } - private JPanel getFixedHightPanel() + private JButton getNextPatternButton() { - if (fixedHightPanel==null) + if (nextPatternButton==null) { - fixedHightPanel = new JPanel(); - fixedHightPanel.setLayout(new GridBagLayout()); - fixedHightPanel.add(getPrevPatternButton(), Helpers.getGridBagConstraint(0, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); - fixedHightPanel.add(getNextPatternButton(), Helpers.getGridBagConstraint(1, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0)); - fixedHightPanel.add(getScrollPane_ArrangementData(), Helpers.getGridBagConstraint(2, 0, 1, 0, java.awt.GridBagConstraints.BOTH, java.awt.GridBagConstraints.WEST, 1.0, 1.0)); - final FontMetrics metrics = fixedHightPanel.getFontMetrics(Helpers.getDialogFont()); - final Dimension d = new Dimension(metrics.charWidth('0'), metrics.getHeight()*4); - //fixedHightPanel.setSize(d); - fixedHightPanel.setMinimumSize(d); - //fixedHightPanel.setMaximumSize(d); - //fixedHightPanel.setPreferredSize(d); + nextPatternButton = new JButton(); + nextPatternButton.setName("nextPatternButton"); + nextPatternButton.setText(">>"); + nextPatternButton.setFont(Helpers.getDialogFont()); + nextPatternButton.setToolTipText("Show previous pattern"); + nextPatternButton.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + if (arrangement!=null && currentIndex<(arrangement.length-1)) + fillWithArrangementIndex(currentIndex+1); + } + }); } - return fixedHightPanel; + return nextPatternButton; } - public JLabel getLabelArrangement() + private JCheckBox getFollowSongCheckBox() { - if (labelArrangement==null) + if (followSongCheckBox==null) { - labelArrangement = new JLabel(); - labelArrangement.setName("labelArrangement"); - labelArrangement.setText("Song arrangement:"); - labelArrangement.setFont(Helpers.getDialogFont()); + followSongCheckBox = new JCheckBox(); + followSongCheckBox.setName("followSongCheckBox"); + followSongCheckBox.setText("Follow song"); + followSongCheckBox.setFont(Helpers.getDialogFont()); + followSongCheckBox.setToolTipText("Control whether to follow the song or not"); + followSongCheckBox.setSelected(true); + // When "follow Song" is not selected, make the caret a bit lighter in color + followSongCheckBox.addItemListener(new ItemListener() + { + @Override + public void itemStateChanged(ItemEvent e) + { + if (e.getStateChange()==ItemEvent.SELECTED || e.getStateChange()==ItemEvent.DESELECTED) + { + if (!getFollowSongCheckBox().isSelected()) + getTextView_PatternData().setSelectionColor(EVENLIGHTERGRAY); + else + getTextView_PatternData().setSelectionColor(LIGHTERGRAY); + } + } + }); } - return labelArrangement; + return followSongCheckBox; } private JScrollPane getScrollPane_ArrangementData() { @@ -363,11 +555,65 @@ private JPanel getArrangementPanel() { if (arrangementPanel==null) { - arrangementPanel = new JPanel(); + arrangementPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); fillButtonsForArrangement(); } return arrangementPanel; } + private JToggleButton createButtonForIndex(final int index, final int arrangementIndex, final Dimension size) + { + JToggleButton newButton = new JToggleButton(); + newButton.setName("ArrangementButton_" + index); + newButton.setText((arrangementIndex>-1)?ModConstants.getAsHex(arrangementIndex, 2):"--"); + newButton.setFont(Helpers.getDialogFont()); + newButton.setToolTipText("Show pattern " + arrangementIndex + " of arrangement index " + index); + newButton.setMargin(Helpers.NULL_INSETS); + newButton.setSize(size); + newButton.setMinimumSize(size); + newButton.setMaximumSize(size); + newButton.setPreferredSize(size); + if (arrangementIndex>-1) + { + newButton.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent evt) + { + fillWithArrangementIndex(index); + } + }); + } + return newButton; + } + private void fillButtonsForArrangement() + { + final int length = (arrangement==null)?25:arrangement.length; + + getArrangementPanel().removeAll(); + buttonGroup = new ButtonGroup(); + + buttonArrangement = new JToggleButton[length]; + for (int i=0; i-1)?Integer.toString(arrangementIndex):"--"); - newButton.setFont(Helpers.getDialogFont()); - newButton.setToolTipText("Show pattern " + arrangementIndex + " of arrangement index " + index); - if (arrangementIndex>-1) + if (patternNumberLabel==null) { - newButton.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent evt) - { - fillWithArrangementIndex(index); - } - }); + patternNumberLabel = new JLabel(); + patternNumberLabel.setName("patternNumberLabel"); + patternNumberLabel.setText(Helpers.EMPTY_STING); + patternNumberLabel.setHorizontalAlignment(SwingConstants.CENTER); + patternNumberLabel.setVerticalAlignment(SwingConstants.CENTER); + patternNumberLabel.setFont(Helpers.getDialogFont()); + patternNumberLabel.setToolTipText("Current number of pattern"); + patternNumberLabel.setOpaque(true); + patternNumberLabel.setBackground(LIGHTESTGRAY); + patternNumberLabel.setBorder(null); } - return newButton; + return patternNumberLabel; } - private JButton getPrevPatternButton() + private JPanel getChannelHeadlinePanel() { - if (prevPatternButton==null) + if (channelHeadlinePanel==null) { - prevPatternButton = new JButton(); - prevPatternButton.setName("prevPatternButton"); - prevPatternButton.setText("<<"); - prevPatternButton.setFont(Helpers.getDialogFont()); - prevPatternButton.setToolTipText("Show previous pattern"); - prevPatternButton.addActionListener(new ActionListener() + channelHeadlinePanel = new JPanel(new GridBagLayout()); + channelHeadlinePanel.setBackground(getTextView_PatternData().getBackground()); + } + return channelHeadlinePanel; + } + /** + * @since 28.11.2023 + * @param channel + * @param highLeft + * @param highRight + * @return + */ + private String createChannelName(final int channel, final int highLeft, final int highRight) + { + StringBuilder sb = new StringBuilder(""); + for (int i=7; i>0; i--) sb.append("("); + sb.append(' ').append(channel+1).append(' '); + for (int i=0; i<8; i++) sb.append(")"); + sb.append(""); + return sb.toString(); + } + /** + * @since 28.11.2023 + * @param channelNumber + * @return + */ + private JButton createChannelButton(final int channelNumber) + { + final JButton channelButton = new JButton(); + channelButton.setName("Channel_"+Integer.toString(channelNumber)); + channelButton.setText(createChannelName(channelNumber, 0, 0)); + channelButton.setHorizontalAlignment(SwingConstants.CENTER); + channelButton.setFont(Helpers.getDialogFont()); + channelButton.setToolTipText("Channel " + Integer.toString(channelNumber) + " mute/unmute"); + channelButton.setBackground(LIGHTESTGRAY); + channelButton.setBorder(null); + channelButton.setBorderPainted(false); + channelButton.setMargin(Helpers.NULL_INSETS); + channelButton.setSize(CHANNELBUTTON_SIZE); + channelButton.setMinimumSize(CHANNELBUTTON_SIZE); + channelButton.setMaximumSize(CHANNELBUTTON_SIZE); + channelButton.setPreferredSize(CHANNELBUTTON_SIZE); + channelButton.addActionListener( + new ActionListener() { - @Override public void actionPerformed(ActionEvent e) { - if (arrangement!=null && currentIndex>0) - fillWithArrangementIndex(currentIndex-1); + doMute(TOGGLEMUTE, channelNumber); } }); + channelButton.addMouseListener(new MouseAdapter() + { + public void mousePressed(MouseEvent e) + { + if (e.isConsumed()) return; + if (SwingUtilities.isRightMouseButton(e)) + { + selectedChannelNumber = channelNumber; + getPopup().show(channelButton, e.getX(), e.getY()); + e.consume(); + } + } + }); + return channelButton; + } + private JLabel createEffectLabel(final int channelNumber) + { + final JLabel effektLabel = new JLabel(); + effektLabel.setName("EffectLabel_"+Integer.toString(channelNumber)); + effektLabel.setText(Helpers.EMPTY_STING); + effektLabel.setHorizontalAlignment(SwingConstants.LEFT); + effektLabel.setFont(Helpers.getDialogFont()); + effektLabel.setToolTipText("Channel " + Integer.toString(channelNumber) + " current effect"); + effektLabel.setOpaque(true); + effektLabel.setBackground(LIGHTESTGRAY); + effektLabel.setBorder(null); + effektLabel.setSize(CHANNELBUTTON_SIZE); + effektLabel.setMinimumSize(CHANNELBUTTON_SIZE); + effektLabel.setMaximumSize(CHANNELBUTTON_SIZE); + effektLabel.setPreferredSize(CHANNELBUTTON_SIZE); + return effektLabel; + } + private JLabel createVolEffectLabel(final int channelNumber) + { + final JLabel volEffectLabel = new JLabel(); + volEffectLabel.setName("VolEffectLabel_"+Integer.toString(channelNumber)); + volEffectLabel.setText(Helpers.EMPTY_STING); + volEffectLabel.setHorizontalAlignment(SwingConstants.LEFT); + volEffectLabel.setFont(Helpers.getDialogFont()); + volEffectLabel.setToolTipText("Channel " + Integer.toString(channelNumber) + " current volume effect"); + volEffectLabel.setOpaque(true); + volEffectLabel.setBackground(LIGHTESTGRAY); + volEffectLabel.setBorder(null); + volEffectLabel.setSize(CHANNELBUTTON_SIZE); + volEffectLabel.setMinimumSize(CHANNELBUTTON_SIZE); + volEffectLabel.setMaximumSize(CHANNELBUTTON_SIZE); + volEffectLabel.setPreferredSize(CHANNELBUTTON_SIZE); + return volEffectLabel; + } + /** + * Create the buttons for the channels + * @since 27.11.2023 + * @param channels + */ + private void createChannelButtons(final int channels) + { + channelButtons = new JButton[channels]; + effectLabels = new JLabel[channels]; + volEffectLabels = new JLabel[channels]; + + for (int i=0; i>"); - nextPatternButton.setFont(Helpers.getDialogFont()); - nextPatternButton.setToolTipText("Show previous pattern"); - nextPatternButton.addActionListener(new ActionListener() - { - @Override - public void actionPerformed(ActionEvent e) - { - if (arrangement!=null && currentIndex<(arrangement.length-1)) - fillWithArrangementIndex(currentIndex+1); - } - }); + getChannelHeadlinePanel().add(channelButtons[i], Helpers.getGridBagConstraint(i, 0, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0, Helpers.NULL_INSETS)); + getChannelHeadlinePanel().add(volEffectLabels[i], Helpers.getGridBagConstraint(i, 1, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0, Helpers.NULL_INSETS)); + getChannelHeadlinePanel().add(effectLabels[i], Helpers.getGridBagConstraint(i, 2, 1, 1, java.awt.GridBagConstraints.NONE, java.awt.GridBagConstraints.WEST, 0.0, 0.0, Helpers.NULL_INSETS)); } - return nextPatternButton; + // Hack: to make the buttons stay and not get horizontally centered, we give the panel something to make bigger instead. + EMPTY_LABEL_CONSTRAINT_CHANNEL.gridx = channels; + getChannelHeadlinePanel().add(EMPTY_LABLE_CHANNEL, EMPTY_LABEL_CONSTRAINT_CHANNEL); + + EventQueue.invokeLater(new Runnable() + { + public void run() + { + getChannelHeadlinePanel().repaint(); + } + }); + } + /** + * Get the row headers for the JScrollPane, so we see the rows + * @since 27.11.2023 + * @return + */ + private JPanel getRowHeadlinePanel() + { + if (rowHeadlinePanel==null) + { + rowHeadlinePanel = new JPanel(new GridBagLayout()); + rowHeadlinePanel.setBackground(getTextView_PatternData().getBackground()); + } + return rowHeadlinePanel; + } + /** + * Create the label for that specific row. + * @since 27.11.2023 + * @param rowNumber + * @return + */ + private JLabel createRowLabel(final int rowNumber) + { + final JLabel rowLabel = new JLabel(); + rowLabel.setName("Row_"+Integer.toString(rowNumber)); + rowLabel.setText(ModConstants.getAsHex(rowNumber, 2)); + rowLabel.setHorizontalAlignment(SwingConstants.CENTER); + rowLabel.setFont(Helpers.getDialogFont()); + rowLabel.setToolTipText("Row " + Integer.toString(rowNumber)); + rowLabel.setOpaque(true); + rowLabel.setBackground((rowNumber%4)==0?LIGHTERGRAY:LIGHTESTGRAY); + rowLabel.setBorder(null); + rowLabel.setSize(PATTERNBUTTON_SIZE); + rowLabel.setMinimumSize(PATTERNBUTTON_SIZE); + rowLabel.setMaximumSize(PATTERNBUTTON_SIZE); + rowLabel.setPreferredSize(PATTERNBUTTON_SIZE); + return rowLabel; + } + /** + * create an amount of labels in advance, so we afterwards only need + * to add the labels with their constraints respectively. + * We need a gridbag so the labels will be stacked - and not side by side. + * @since 27.11.2023 + * @param maxRows + */ + private void createRowLabels(final int maxRows) + { + if (rowLabels!=null && rowLabels.length>=maxRows) return; + + int start = 0; + if (rowLabels==null) + { + rowLabels = new JLabel[maxRows]; + rowLabelConstraints = new GridBagConstraints[maxRows]; + } + else + if (maxRows>rowLabels.length) // if we already created rowLabels, check if we have enough! + { + start = rowLabels.length; + JLabel [] newRowLabels = new JLabel[maxRows]; + GridBagConstraints [] newRowLabelConStraints = new GridBagConstraints[maxRows]; + + System.arraycopy(rowLabels, 0, newRowLabels, 0, rowLabels.length); + System.arraycopy(rowLabelConstraints, 0, newRowLabelConStraints, 0, rowLabelConstraints.length); + rowLabels = newRowLabels; + rowLabelConstraints = newRowLabelConStraints; + } + + for (int i=start; i rowLabels.length) createRowLabels(rows); + + getRowHeadlinePanel().removeAll(); + for (int i=0; i=0; row--) -// { -// PatternElement [] patternElements = patternRows[row].getPatternElements(); -// if (patternElements!=null) -// { -// final ArrayList elementSpecs = new ArrayList(); -// -// String line = patternRows[row].toString(); -// -// elementSpecs.add(new ElementSpec(foregroundAttSet, ElementSpec.ContentType, (ModConstants.getAsHex(row, 2) + " |").toCharArray(), 0, 4)); -// for (int c=0; c=muteStatus.length || !muteStatus[i])?Color.black:Color.lightGray; + channelButtons[i].setForeground(c); + } } - else + } + /** + * @since 28.11.2023 + * @param whatMute + * @param channelNumber + */ + private void doMute(final int whatMute, final int channelNumber) + { + selectedChannelNumber = channelNumber; + if (currentMixer!=null) { - for (int i=0; i> work + currentIndex = index; + + EventQueue.invokeLater(new Runnable() + { + public void run() + { + try + { + final int patternIndex = arrangement[index]; + // set the correct Button of the arrangement + final JToggleButton theButton = buttonArrangement[index]; + theButton.setSelected(true); + + // create the row labels according to # of rows of this pattern and display it + final Pattern pattern = patternContainer.getPattern(patternIndex); + fillLabelsForRows(pattern.getRowCount()); + + // fill with pattern data + getTextView_PatternData().setText(pattern.toPatternDataString(false)); + + getPatternNumberLabel().setText("#"+ModConstants.getAsHex(patternIndex, 2)); + + // now scroll everything to become visible + getArrangementPanel().scrollRectToVisible(theButton.getBounds()); + getTextView_PatternData().setCaretPosition(0); + getTextView_PatternData().moveCaretPosition(0); + getScrollPane_PatternData().getVerticalScrollBar().setValue(0); // otherwise will never see the 0 row + } + catch (Throwable ex) + { + // Keep it! + } + } + }); + } + /** + * This method will get called from outside to set a new MOD. + * If we have a mixer currently playing, there might still come updates from + * there for a mod we do not represent anymore. We need to kill all.. + * @since 28.11.2023 + * @param songLength + * @param newArrangement + * @param newPatternContainer + */ + public void fillWithPatternArray(final int songLength, final int [] newArrangement, final PatternContainer newPatternContainer) + { + // we receive Data for a new mod. If the old one is playing, stop any updates on that one + stopUpdateThread(); + + EventQueue.invokeLater(new Runnable() + { + public void run() + { + getTextView_PatternData().setCaretPosition(0); + getTextView_PatternData().moveCaretPosition(0); + getScrollPane_PatternData().getVerticalScrollBar().setValue(0); + getScrollPane_PatternData().getHorizontalScrollBar().setValue(0); + } + }); + + patternContainer = newPatternContainer; + + // We need to copy the arrangement to songLength values + arrangement = new int [songLength]; + for (int i=0; i0 && buttonArrangement[0]!=null) - fillWithArrangementIndex(0); + + createChannelButtons(patternContainer.getChannels()); + fillButtonsForChannels(0, patternContainer.getChannels()); + fillWithArrangementIndex(0); + } + /** + * For mute/unmute we need the current Mixer. + * ModContainer will take care of setting it. If no mixer is present, + * it is set to "null" here! + * @since 28.11.2023 + * @param mixer + */ + public void setMixer(BasicModMixer mixer) + { + currentMixer = mixer; + updateMuteStatus(); // THIS DOES ONLY WORK, OF THE PIECE IN HERE FITS TO THE MIXER! ModContainer takes care of that... + } + /** + * push an event into the songFollower queue + * @param infoObject + * @see de.quippy.javamod.multimedia.mod.gui.ModUpdateListener#getPositionInformation(de.quippy.javamod.multimedia.mod.gui.ModUpdateListener.PositionInformation) + */ + @Override + public void getPositionInformation(PositionInformation infoObject) + { + if (songFollower!=null) songFollower.push(infoObject); + } + /** + * @param infoObject + * @see de.quippy.javamod.multimedia.mod.gui.ModUpdateListener#getPeekInformation(de.quippy.javamod.multimedia.mod.gui.ModUpdateListener.PeekInformation) + */ + @Override + public void getPeekInformation(PeekInformation infoObject) + { + if (songFollower!=null) songFollower.push(infoObject); + } + /** + * @param infoObject + * @see de.quippy.javamod.multimedia.mod.gui.ModUpdateListener#getStatusInformation(de.quippy.javamod.multimedia.mod.gui.ModUpdateListener.StatusInformation) + */ + @Override + public void getStatusInformation(StatusInformation infoObject) + { + if (!infoObject.status) + { + drainUpdateThread(); + resetVolume(); + } + } + /** + * Flush the update Thread buffer + * @since 24.11.2023 + */ + public void flushUpdateThread() + { + if (songFollower!=null) songFollower.flush(); + } + /** + * Drains all events left over. This will also block adding of new events + * till buffer is drained. + * @since 29.11.2023 + */ + public void drainUpdateThread() + { + if (songFollower!=null) songFollower.drain(); + } + /** + * @since 28.11.2023 + * @param doPause + */ + public void pauseUpdateThread(final boolean doPause) + { + if (songFollower!=null) songFollower.pause(doPause); + } + /** + * Stop the thread + * @since 13.11.2023 + */ + public void stopUpdateThread() + { + if (songFollower!=null) + { + songFollower.stopMe(); + songFollower = null; + } + } + /** + * Create and start the Thread + * @since 13.11.2023 + */ + public void startUpdateThread() + { + if (songFollower!=null) stopUpdateThread(); + songFollower = new SongFollower(); + songFollower.start(); } } diff --git a/source/de/quippy/javamod/multimedia/mod/gui/ModSampleDialog.java b/source/de/quippy/javamod/multimedia/mod/gui/ModSampleDialog.java index f9e1cbf..400c45c 100644 --- a/source/de/quippy/javamod/multimedia/mod/gui/ModSampleDialog.java +++ b/source/de/quippy/javamod/multimedia/mod/gui/ModSampleDialog.java @@ -34,12 +34,14 @@ import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.SpinnerListModel; +import javax.swing.JSpinner.DefaultEditor; import javax.swing.border.TitledBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import de.quippy.javamod.main.gui.tools.FixedStateCheckBox; import de.quippy.javamod.multimedia.mod.ModConstants; +import de.quippy.javamod.multimedia.mod.ModInfoPanel; import de.quippy.javamod.multimedia.mod.loader.instrument.Sample; import de.quippy.javamod.system.Helpers; @@ -101,13 +103,18 @@ public class ModSampleDialog extends JDialog private JTextField autoVibRateValue = null; private Sample [] samples; + private ArrayList spinnerModelData = null; + + @SuppressWarnings("unused") + private ModInfoPanel myModInfoPanel; /** * Constructor for ModPatternDialog */ - public ModSampleDialog() + public ModSampleDialog(ModInfoPanel infoPanel) { super(); + myModInfoPanel = infoPanel; initialize(); } /** @@ -115,9 +122,10 @@ public ModSampleDialog() * @param owner * @param modal */ - public ModSampleDialog(JFrame owner, boolean modal) + public ModSampleDialog(ModInfoPanel infoPanel, JFrame owner, boolean modal) { super(owner, modal); + myModInfoPanel = infoPanel; initialize(); } /** @@ -125,9 +133,10 @@ public ModSampleDialog(JFrame owner, boolean modal) * @param owner * @param modal */ - public ModSampleDialog(JDialog owner, boolean modal) + public ModSampleDialog(ModInfoPanel infoPanel, JDialog owner, boolean modal) { super(owner, modal); + myModInfoPanel = infoPanel; initialize(); } private void initialize() @@ -158,6 +167,8 @@ public void windowClosing(java.awt.event.WindowEvent e) setPreferredSize(getSize()); pack(); setLocation(Helpers.getFrameCenteredLocation(this, getParent())); + + fillWithSample(null); } public void doClose() { @@ -175,6 +186,10 @@ private JLabel getLabelSelectSample() } return labelSelectSample; } + private int getCurrentSampleIndex() + { + return Integer.parseInt((String)getSelectSample().getModel().getValue(), 16) - 1; + } private JSpinner getSelectSample() { if (selectSample==null) @@ -197,8 +212,7 @@ public void stateChanged(ChangeEvent e) { if (samples!=null) { - Integer sampleIndex = (Integer)getSelectSample().getModel().getValue(); - fillWithSample(samples[sampleIndex.intValue()-1]); + fillWithSample(samples[getCurrentSampleIndex()]); } } }); @@ -825,6 +839,10 @@ private SampleImagePanel getImageBufferPanel() } private void clearSample() { + spinnerModelData = new ArrayList(1); + spinnerModelData.add(ModConstants.getAsHex(0, 2)); + getSelectSample().setModel(new SpinnerListModel(spinnerModelData)); + getSampleType().setText(Helpers.EMPTY_STING); getSampleName().setText(Helpers.EMPTY_STING); getDosFileName().setText(Helpers.EMPTY_STING); @@ -857,6 +875,10 @@ private void fillWithSample(final Sample sample) } else { + spinnerModelData = new ArrayList(samples.length); + for (int i=0; i list = new ArrayList(samples.length); - for (int i=0; i> 48)&0xFFFF); + this.patternRow = (int)((position >> 16)&0xFFFF); + } + + public String toString() + { + return super.toString()+"-->Position: "+ModConstants.getAsHex(patternIndex, 2)+"/"+ModConstants.getAsHex(patternRow, 2); + } + } + public class PeekInformation extends TimedInformation + { + public int channel; + public int actPeekLeft; + public int actPeekRight; + + public PeekInformation(final int sampleRate, final long samplesMixed, final int channel, final long actPeekLeft, final long actPeekRight) + { + super(sampleRate, samplesMixed); + this.channel = channel; + + this.actPeekLeft = (int)(actPeekLeft / 0xFFFFFFF); + if (this.actPeekLeft==0 && actPeekLeft>0) this.actPeekLeft = 1; + this.actPeekRight = (int)(actPeekRight / 0xFFFFFFF); + if (this.actPeekRight==0 && actPeekRight>0) this.actPeekRight = 1; + } + public String toString() + { + return super.toString()+"-->Peek: "+channel+": " + actPeekLeft + "/" + actPeekRight; + } + } + public class StatusInformation + { + public boolean status; + + public StatusInformation(final boolean newStatus) + { + status = newStatus; + } public String toString() { - final int index = (int)((position >> 48)&0xFFFF); - final int row = (int)((position >> 16)&0xFFFF); - return samplesMixed+"/"+timeCode+"-->"+ModConstants.getAsHex(index, 2)+"/"+ModConstants.getAsHex(row, 2); + return "Status: " + Boolean.toString(status); } } /** @@ -51,5 +107,7 @@ public String toString() * @since 13.11.2023 * @param infoObject */ - public void getMixerInformation(final InformationObject infoObject); + public void getPositionInformation(final PositionInformation infoObject); + public void getPeekInformation(final PeekInformation infoObject); + public void getStatusInformation(final StatusInformation infoObject); } diff --git a/source/de/quippy/javamod/multimedia/mod/loader/pattern/Pattern.java b/source/de/quippy/javamod/multimedia/mod/loader/pattern/Pattern.java index c518dc4..b1db855 100644 --- a/source/de/quippy/javamod/multimedia/mod/loader/pattern/Pattern.java +++ b/source/de/quippy/javamod/multimedia/mod/loader/pattern/Pattern.java @@ -30,6 +30,9 @@ public class Pattern { private PatternRow [] patternRows; + public static int LINEINDEX_LENGTH = 4; + public static int ROW_LENGTH = 16; + /** * Constructor for Pattern */ @@ -41,7 +44,7 @@ public Pattern(int rows) public Pattern(int rows, int channels) { this(rows); - for (int i=0; i0) return 4 + patternRows[0].getPatternRowCharacterLength(); else return 4; + for (int row=0; row0 && patternRows[0]!=null)?patternRows[0].getChannels():0; + } /** * @since 23.08.2008 */ diff --git a/source/de/quippy/javamod/multimedia/mod/loader/pattern/PatternContainer.java b/source/de/quippy/javamod/multimedia/mod/loader/pattern/PatternContainer.java index 4316eb6..82fa7e3 100644 --- a/source/de/quippy/javamod/multimedia/mod/loader/pattern/PatternContainer.java +++ b/source/de/quippy/javamod/multimedia/mod/loader/pattern/PatternContainer.java @@ -55,16 +55,36 @@ public String toString() { StringBuilder sb = new StringBuilder(); for (int i=0; i0 && pattern[0]!=null)?pattern[0].getChannels():0; + } /** * @since 23.08.2008 */ public void resetRowsPlayed() { for (int i=0; i0) - return patternElements.length * 16; - else - return 0; + final PatternElement[] newPatternElements = new PatternElement[nChannels]; + for (int channel=0; channel 0x400) continue; inputStream.skip(4); // RESERVED @@ -781,6 +789,7 @@ protected void loadModFileInternal(final ModfileInputStream inputStream) throws } if (maxChannels<4) maxChannels=4; setNChannels(maxChannels+1); + patternContainer.setToChannels(getNChannels()); // Correct the songlength for playing, skip markerpattern... (do not want to skip them during playing!) int realLen = 0; diff --git a/source/de/quippy/javamod/multimedia/mod/loader/tracker/XMMod.java b/source/de/quippy/javamod/multimedia/mod/loader/tracker/XMMod.java index f1592ae..97dd06c 100644 --- a/source/de/quippy/javamod/multimedia/mod/loader/tracker/XMMod.java +++ b/source/de/quippy/javamod/multimedia/mod/loader/tracker/XMMod.java @@ -269,27 +269,24 @@ protected void loadModFileInternal(ModfileInputStream inputStream) throws IOExce for (int pattNum=0; pattNum0) + for (int row=0; row0) setIntoPatternElement(currentElement, inputStream); + currentRow.setPatternElement(channel, currentElement); } + currentPattern.setPatternRow(row, currentRow); } patternContainer.setPattern(pattNum, currentPattern); } diff --git a/source/de/quippy/javamod/multimedia/mod/mixer/BasicModMixer.java b/source/de/quippy/javamod/multimedia/mod/mixer/BasicModMixer.java index c909cc4..2996aac 100644 --- a/source/de/quippy/javamod/multimedia/mod/mixer/BasicModMixer.java +++ b/source/de/quippy/javamod/multimedia/mod/mixer/BasicModMixer.java @@ -26,6 +26,9 @@ import de.quippy.javamod.multimedia.mod.ModConstants; import de.quippy.javamod.multimedia.mod.gui.ModUpdateListener; +import de.quippy.javamod.multimedia.mod.gui.ModUpdateListener.PeekInformation; +import de.quippy.javamod.multimedia.mod.gui.ModUpdateListener.PositionInformation; +import de.quippy.javamod.multimedia.mod.gui.ModUpdateListener.StatusInformation; import de.quippy.javamod.multimedia.mod.loader.Module; import de.quippy.javamod.multimedia.mod.loader.instrument.Envelope; import de.quippy.javamod.multimedia.mod.loader.instrument.Instrument; @@ -43,7 +46,7 @@ public abstract class BasicModMixer public class ChannelMemory { public int channelNumber; - public boolean muted; + public boolean muted, wasITforced; public boolean isNNA; public PatternElement currentElement; @@ -73,6 +76,9 @@ public class ChannelMemory public int actRampVolLeft, actRampVolRight, deltaVolLeft, deltaVolRight; public int channelVolumSlideValue; + // only needed for display + public long bigSampleLeft, bigSampleRight; + public boolean doSurround; public int autoVibratoTablePos, autoVibratoAmplitude; @@ -129,7 +135,7 @@ public ChannelMemory() channelVolumSlideValue = 0; fadeOutVolume = ModConstants.MAXFADEOUTVOLUME; - muted = false; + muted = false; wasITforced = false; assignedNotePeriod = currentNotePeriod = currentNotePeriodSet = currentFinetuneFrequency = currentFineTune = 0; currentTuning = currentTuningPos = currentSamplePos = interpolationMagic = loopCounter = 0; @@ -381,6 +387,9 @@ public String toString() // The listeners for update events - so far only one known off private ArrayList listeners; private boolean fireUpdates = false; + + private boolean isFastTracker, isScreamTracker, isMOD, isXM, /*isSTM,*/ isS3M, isIT; + /** * Constructor for BasicModMixer @@ -446,7 +455,7 @@ public void changeMaxNNAChannels(final int newMaxNNAChannels) maxNNAChannels = newMaxNNAChannels; final int nChannels = mod.getNChannels(); int newMaxChannels = nChannels; - if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) + if (isIT) newMaxChannels += maxNNAChannels; if (newMaxChannels!=maxChannels) { @@ -482,6 +491,14 @@ public void initializeMixer() // to be a bit faster, we do some pre-calculations calculateGlobalTuning(); + isFastTracker=(mod.getModType()&ModConstants.MODTYPE_FASTTRACKER)!=0; + isScreamTracker=(mod.getModType()&ModConstants.MODTYPE_SCREAMTRACKER)!=0; + isMOD=(mod.getModType()&ModConstants.MODTYPE_MOD)!=0; + isXM=(mod.getModType()&ModConstants.MODTYPE_XM)!=0; + //isSTM=(mod.getModType()&ModConstants.MODTYPE_STM)!=0; + isS3M=(mod.getModType()&ModConstants.MODTYPE_S3M)!=0; + isIT=(mod.getModType()&ModConstants.MODTYPE_IT)!=0; + // get Mod specific values frequencyTableType = mod.getFrequencyTable(); currentTempo = mod.getTempo(); @@ -489,7 +506,7 @@ public void initializeMixer() globalVolume = mod.getBaseVolume(); globalFilterMode = false; // IT default: every note resets filter to current values set - flattens the filter envelope - swinger = new Random(0xAFFEAFFEAFFEAFFEL); + swinger = new Random(); if ((mod.getModType()&ModConstants.MODTYPE_MPT)==ModConstants.MODTYPE_MPT) // Legacy MPT? { @@ -525,7 +542,7 @@ public void initializeMixer() useSoftPanning = true; } // else // Open ModPlug does it like this but we will not - too loud. FT2 with default AMP x4 is even more silent -// if ((mod.getModType()&ModConstants.MODTYPE_XM)==ModConstants.MODTYPE_XM) // XM Mod? +// if (isXM) // { // masterVolume = mod.getMixingPreAmp(); // extraAttenuation = 0; @@ -565,7 +582,7 @@ public void initializeMixer() // initialize every used channel final int nChannels = mod.getNChannels(); maxChannels = nChannels; - if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) + if (isIT) maxChannels += maxNNAChannels; channelMemory = new ChannelMemory[maxChannels]; for (int c=0; c0) @@ -1025,6 +1042,21 @@ private void doResonance(final ChannelMemory aktMemo, final long buffer[]) * @return */ protected abstract int getEffektOpMemory(final ChannelMemory aktMemo, final int effekt, final int effektParam); + /** + * This will return the name of the current effekt referenced by aktMemo + * @since 30.11.2023 + * @param aktMemo + * @return + */ + public abstract String getEffectName(final int effekt, final int effektParam); + /** + * This will return the name of the current volume column effect + * @since 30.11.2023 + * @param volumeEffekt + * @param volumeEffektOp + * @return + */ + public abstract String getVolEffectName(final int volumeEffekt, final int volumeEffektOp); /** * @since 19.06.2020 * @param aktMemo @@ -1050,8 +1082,6 @@ protected void processEnvelopes(ChannelMemory aktMemo) int currentVolume = aktMemo.currentVolume << ModConstants.VOLUMESHIFT; // typically it's the sample volume or a volume set 0..64 int currentPanning = aktMemo.panning; int currentPeriod = aktMemo.currentNotePeriodSet; - final boolean isIT = (mod.getModType()&ModConstants.MODTYPE_IT)!=0; - final boolean isXM = (mod.getModType()&ModConstants.MODTYPE_XM)!=0; // The adjustments on the periods will change currentNotePeriodSet // That's bad in envelopes, because we want to "add on" here @@ -1136,7 +1166,7 @@ protected void processEnvelopes(ChannelMemory aktMemo) { // XMs do hard note cut, if no volumeEnv or not enabled if (isXM && (volumeEnv==null || !volumeEnv.on)) - currentVolume = aktMemo.fadeOutVolume = 0; + currentVolume = aktMemo.currentVolume = aktMemo.fadeOutVolume = 0; else // otherwise activate note fade, if not yet done initNoteFade(aktMemo); } @@ -1175,42 +1205,36 @@ protected void processEnvelopes(ChannelMemory aktMemo) currentVolume = (currentVolume * loopingFadeOutValue) >> ModConstants.MAXFADEOUTVOLSHIFT; // Global Volumes currentVolume = (int)((((long)currentVolume * (long)globalVolume * (long)insVolume * (long)aktMemo.channelVolume) + (1<<(ModConstants.VOLUMESHIFT-1)) ) >> (7+7+6)); - // now for MasterVolume - which is SamplePreAmp, changed because of legacy MPT: - if (useGlobalPreAmp) - { - currentVolume = (currentVolume * masterVolume) >> (ModConstants.PREAMP_SHIFT - 1); - } + currentVolume = (currentVolume * masterVolume) >> ((useGlobalPreAmp)?(ModConstants.PREAMP_SHIFT - 1):ModConstants.PREAMP_SHIFT); + + // Clipping Volume + if (currentVolume<=0) currentVolume=0; else - { - currentVolume = (currentVolume * masterVolume) >> ModConstants.PREAMP_SHIFT; - } + if (currentVolume>ModConstants.MAXCHANNELVOLUME) currentVolume=ModConstants.MAXCHANNELVOLUME; } - // Clipping Volume - if (currentVolume<=0) currentVolume=0; - else - if (currentVolume>ModConstants.MAXCHANNELVOLUME) currentVolume=ModConstants.MAXCHANNELVOLUME; - currentPanning += aktMemo.swingPanning; // Random value -128..+128 if (currentPanning<0) currentPanning=0; else if (currentPanning>256) currentPanning=256; int panSep = mod.getPanningSeparation(); - if (panSep<128) // skip calc if not needed... + if (panSep<128) // skip calculation if not needed... { - currentPanning -=128; + currentPanning -= 128; currentPanning = (currentPanning * panSep)>>7; - currentPanning +=128; + currentPanning += 128; } // IT Compatibility: Ensure that there is no pan swing, panbrello, panning envelopes, etc. applied on surround channels. if (isIT && aktMemo.doSurround) currentPanning = 128; + // save current channel volume set aktMemo.actRampVolLeft = aktMemo.actVolumeLeft; aktMemo.actRampVolRight = aktMemo.actVolumeRight; + // calculate new channel volume depending on currentVolume and panning if ((mod.getSongFlags()&ModConstants.SONG_ISSTEREO)==0) { aktMemo.actVolumeLeft = aktMemo.actVolumeRight = currentVolume; @@ -1298,8 +1322,7 @@ protected void processEnvelopes(ChannelMemory aktMemo) */ protected void doPanning(final ChannelMemory aktMemo, int param, ModConstants.PanBits bits) { - final int modType = mod.getModType(); - if ((modType&ModConstants.MODTYPE_MOD)!=0) return; + if (isMOD) return; aktMemo.doSurround = false; if (bits == ModConstants.PanBits.Pan4Bit) // 0..15 @@ -1315,11 +1338,7 @@ protected void doPanning(final ChannelMemory aktMemo, int param, ModConstants.Pa else { // ModConstants.PanBits.Pan8Bit // 0..255 - if ((modType&ModConstants.MODTYPE_S3M)==0) - { - aktMemo.panning = param&0xFF; - } - else + if (isS3M) { // This is special operation for S3M // ModConstants.PanBits.Pan8Bit now // 0..128 @@ -1334,6 +1353,10 @@ protected void doPanning(final ChannelMemory aktMemo, int param, ModConstants.Pa aktMemo.panning = 0x80; } } + else + { + aktMemo.panning = param&0xFF; + } } aktMemo.swingPanning = 0; } @@ -1607,7 +1630,7 @@ protected void doNNAforAllof(final ChannelMemory aktMemo, final int NNA) */ protected void doNNAAutoInstrument(ChannelMemory aktMemo) { - if ((mod.getModType()&ModConstants.MODTYPE_IT)==0 || !isChannelActive(aktMemo) || aktMemo.muted || aktMemo.noteCut) return; + if (!isIT || !isChannelActive(aktMemo) || aktMemo.muted || aktMemo.noteCut) return; Instrument currentInstrument = aktMemo.assignedInstrument; if (currentInstrument!=null) @@ -1691,17 +1714,16 @@ protected void resetForNewSample(final ChannelMemory aktMemo) protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) { final PatternElement element = aktMemo.currentElement; + final boolean isPortaToNoteEffekt = isPortaToNoteEffekt(aktMemo.currentEffekt, aktMemo.currentEffektParam, aktMemo.currentVolumeEffekt, aktMemo.currentVolumeEffektOp, aktMemo.currentAssignedNotePeriod); // Do Instrument default NNA if ((element.getPeriod()>0 || element.getNoteIndex()>0) && - !isPortaToNoteEffekt(aktMemo.currentEffekt, aktMemo.currentEffektParam, aktMemo.currentVolumeEffekt, aktMemo.currentVolumeEffektOp, aktMemo.currentAssignedNotePeriod) && + !isPortaToNoteEffekt && !isNNAEffekt(aktMemo.currentEffekt, aktMemo.currentEffektParam)) // New Note Action { doNNAAutoInstrument(aktMemo); } - // do we have an instrument change? Need that as an exception for porta to note - boolean instrumentChange = (aktMemo.currentAssignedInstrumentIndex>0 && aktMemo.currentAssignedInstrumentIndex != aktMemo.assignedInstrumentIndex); // copy last seen values from pattern aktMemo.assignedNotePeriod = aktMemo.currentAssignedNotePeriod; aktMemo.assignedNoteIndex = aktMemo.currentAssignedNoteIndex; @@ -1709,55 +1731,72 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) aktMemo.effektParam = aktMemo.currentEffektParam; aktMemo.volumeEffekt = aktMemo.currentVolumeEffekt; aktMemo.volumeEffektOp = aktMemo.currentVolumeEffektOp; - aktMemo.assignedInstrumentIndex = aktMemo.currentAssignedInstrumentIndex; - aktMemo.assignedInstrument = aktMemo.currentAssignedInstrument; + // Before copying the last seen instrument, check for volume sets if (element.getInstrument()>0) { - Instrument newInstrument = aktMemo.assignedInstrument; // same as element.getInstrument - in this case. Was copied - // Get the correct sample from the mapping table, if there is an instrument set - Sample newSample = (newInstrument!=null)? - ((aktMemo.assignedNoteIndex>0)? // but only if we also have a note index, if not, ignore it! - mod.getInstrumentContainer().getSample(newInstrument.getSampleIndex(aktMemo.assignedNoteIndex-1)) - :null) - :mod.getInstrumentContainer().getSample(aktMemo.assignedInstrumentIndex-1); -// The above in normal code :) -// Sample newSample = null; -// if (newInstrument!=null) -// { -// // but only if we also have a note index, if not, ignore it! -// if (aktMemo.assignedNoteIndex>0) newSample = mod.getInstrumentContainer().getSample(newInstrument.getSampleIndex(aktMemo.assignedNoteIndex-1)); -// } -// else -// newSample = mod.getInstrumentContainer().getSample(aktMemo.assignedInstrumentIndex-1); - - // Normally Volume and panning is set here. - // With FastTracker however (FastTracker 2.09!), these values - // are not used, if there is a new(!) sample with no note. Then - // ignore them (only, if it is the same...) - // Long running samples are "reactivated", because volume of - // zero is reset to sample default volume. They are however - // not "re-triggered" - if (!((mod.getModType()&(ModConstants.MODTYPE_XM))!=0 && newSample!=aktMemo.currentSample && (element.getPeriod()==0 && element.getNoteIndex()==0))) + // Volume and panning is set here. + // Long running samples are "reactivated", because volume of zero is reset to sample default volume. They are however not "re-triggered" + // BUT, if this is a PortaToNote effect with a long looping instrument, need to use old instrument / sample set... + if (isPortaToNoteEffekt && !aktMemo.instrumentFinished) { + // There is a really oddly different behavior between Screamtracker, Fasttracker, ModPlug and Schismtracker + // Schism sets all values from the new instrument/sample set - even the tuning! + // Fasttracker will ignore the new instrument/sample and use the old one + // ScreamTracker 2.14v5 does the same + // Modplug however takes the volume of the old instrument but - with ITs - the panning from the new one + // We cannot do all - so we will rely on FT2.09 and IT2.14 behavior - except: if no instrument is playing, set the new one! int panning = -1; - if (newInstrument!=null) + if (aktMemo.assignedInstrument!=null) { - panning = newInstrument.defaultPan; + panning = aktMemo.assignedInstrument.defaultPan; if (panning!=-1) aktMemo.panning = panning; } - if (newSample!=null) + if (aktMemo.currentSample!=null) { - aktMemo.savedCurrentVolume = aktMemo.currentVolume = newSample.volume; + aktMemo.savedCurrentVolume = aktMemo.currentVolume = aktMemo.currentSample.volume; if (panning==-1) { - panning = newSample.panning; + panning = aktMemo.currentSample.panning; if (panning!=-1) aktMemo.panning = panning; } } } + else // no Porta to note, so use current. With FastTracker however (FastTracker 2.09!), this is not done, if there is a new(!) sample with no note. Then ignore them (only, if it is the same...) + { + Instrument newInstrument = aktMemo.currentAssignedInstrument; // same as mod.getInstrumentContainer().getInstrument(element.getInstrument()-1); - in this case, because was copied + // Get the correct sample from the mapping table, if there is an instrument set + Sample newSample = (newInstrument!=null)? + ((aktMemo.assignedNoteIndex>0)? // but only if we also have a note index, if not, ignore it! + mod.getInstrumentContainer().getSample(newInstrument.getSampleIndex(aktMemo.assignedNoteIndex-1)) + :null) + :mod.getInstrumentContainer().getSample(aktMemo.currentAssignedInstrumentIndex-1); + + if (!(isXM && newSample!=aktMemo.currentSample && (element.getPeriod()==0 && element.getNoteIndex()==0))) + { + int panning = -1; + if (newInstrument!=null) + { + panning = newInstrument.defaultPan; + if (panning!=-1) aktMemo.panning = panning; + } + if (newSample!=null) + { + aktMemo.savedCurrentVolume = aktMemo.currentVolume = newSample.volume; + if (panning==-1) + { + panning = newSample.panning; + if (panning!=-1) aktMemo.panning = panning; + } + } + } + } } - + + // Now safe those instruments for later re-use + aktMemo.assignedInstrumentIndex = aktMemo.currentAssignedInstrumentIndex; + aktMemo.assignedInstrument = aktMemo.currentAssignedInstrument; + // Key Off, Note Cut or Period / noteIndex to set? if (element.getPeriod()==ModConstants.KEY_OFF || element.getNoteIndex()==ModConstants.KEY_OFF) { @@ -1775,27 +1814,27 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) } else if ( ((element.getPeriod()>0 || element.getNoteIndex()>0) || // if there is a note, we need to calc the new tuning and activate a previous set instrument - ((mod.getModType()&ModConstants.MODTYPE_SCREAMTRACKER)!=0 && element.getInstrument()>0)) // but with scream tracker like mods, the old notevalue is used, if an instrument is set - && (!isPortaToNoteEffekt(aktMemo.effekt, aktMemo.effektParam, aktMemo.volumeEffekt, aktMemo.volumeEffektOp, element.getPeriod()) || instrumentChange) // but ignore this if porta to note - but not if instrument change... + (isScreamTracker && element.getInstrument()>0)) // but with scream tracker like mods, the old notevalue is used, if an instrument is set + && (!isPortaToNoteEffekt || aktMemo.instrumentFinished) // but ignore this if porta to note (but do not ignore, if no instrument is playing) ) { final int savedNoteIndex = aktMemo.assignedNoteIndex; // save the noteIndex - if it is changed by an instrument, we use that one to generate the period, but set it back then final Instrument inst = aktMemo.assignedInstrument; boolean newInstrumentWasSet = false; boolean useFilter = !globalFilterMode; - + // We have an instrument assigned, so there was (once) an instrument set! if (inst!=null || aktMemo.assignedInstrumentIndex>0) { Sample newSample = null; - // Get the correct sample from the mapping table - if (inst!=null) + // Get the correct sample from the mapping table, if we have an instrument and a valid noteindex + if (inst!=null && aktMemo.assignedNoteIndex>0) { newSample = mod.getInstrumentContainer().getSample(inst.getSampleIndex(aktMemo.assignedNoteIndex-1)); aktMemo.assignedNoteIndex = inst.getNoteIndex(aktMemo.assignedNoteIndex-1)+1; // Now for some specials of IT - if ((mod.getModType()&(ModConstants.MODTYPE_IT))!=0) + if (isIT) { // Set Resonance! if ((inst.initialFilterResonance & 0x80)!=0) { aktMemo.resonance = inst.initialFilterResonance & 0x7F; useFilter = true; } @@ -1849,8 +1888,7 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) } // With IT this has to be checked! Always! // IT-MODS (and derivates) reset here, because a sample set is relevant (see below) - if ((mod.getModType()&ModConstants.MODTYPE_SCREAMTRACKER)!=0 && - (aktMemo.instrumentFinished || (element.getPeriod()>0 || element.getNoteIndex()>0))) + if (isScreamTracker && (aktMemo.instrumentFinished || (element.getPeriod()>0 || element.getNoteIndex()>0))) { resetAllEffects(aktMemo, element, true); // Reset Tremolo and such things... Forced! because of a new note aktMemo.noteCut = aktMemo.keyOff = aktMemo.noteFade = false; @@ -1861,10 +1899,7 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) } } - // Till now we totally ignored all of the above, if this was a porta to note effect. - // However, at least the instrument should be (re-)set. We only do not set the note period! - // This is not like FT2.09 does it! - if (!isPortaToNoteEffekt(aktMemo.effekt, aktMemo.effektParam, aktMemo.volumeEffekt, aktMemo.volumeEffektOp, element.getPeriod())) + if (!isPortaToNoteEffekt) { // Now set the player Tuning and reset some things in advance. // normally we are here, because a note was set in the pattern. @@ -1873,7 +1908,7 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) // notevalue is to be used. // However, we do not reset the instrument here - the reset was // already done above - so this is here for all sane players :) - if ((mod.getModType()&ModConstants.MODTYPE_SCREAMTRACKER)==0) // MOD, XM... + if (isFastTracker) // MOD, XM... { resetAllEffects(aktMemo, element, true); // Reset Tremolo and such things... Forced! because of a new note aktMemo.noteCut = aktMemo.keyOff = aktMemo.noteFade = false; @@ -1884,7 +1919,7 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) // With impulse tracker, again we are here because of an instrument // set - we should now only reset the tuning (like automatically with // all others) when we have a note/period or a new instrument - if ((mod.getModType()&ModConstants.MODTYPE_SCREAMTRACKER)!=0) + if (isScreamTracker) { if ((element.getPeriod()>0 || element.getNoteIndex()>0) || newInstrumentWasSet) setNewPlayerTuningFor(aktMemo, aktMemo.portaTargetNotePeriod = aktMemo.currentNotePeriod = getFineTunePeriod(aktMemo)); @@ -1898,42 +1933,6 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo) aktMemo.assignedNoteIndex = savedNoteIndex; } } - public void registerUpdateListener(final ModUpdateListener listener) - { - if (listeners!=null && !listeners.contains(listener)) listeners.add(listener); - } - public void deregisterUpdateListener(final ModUpdateListener listener) - { - if (listeners!=null && listeners.contains(listener)) listeners.remove(listener); - } - public void setFireUpdates(final boolean newFireUpdates) - { - fireUpdates = newFireUpdates; - } - public boolean getFireUpdates() - { - return fireUpdates; - } - public void firePositionUpdate() - { - if (listeners!=null && fireUpdates) - { - ModUpdateListener.InformationObject information = new ModUpdateListener.InformationObject(); - information.samplesMixed = samplesMixed; - information.timeCode = (samplesMixed * 1000L) / sampleRate; - information.position = getCurrentPatternPosition(); - for (ModUpdateListener listener : listeners) - { - listener.getMixerInformation(information); - } - // Manual Version, maybe the above is more optimized -// final int size = listeners.size(); -// for (int i=0; i-1 && (doNoLoops&ModConstants.PLAYER_LOOP_LOOPSONG)!=0) { + initializeMixer(); currentArrangement = mod.getSongRestart(); currentPatternIndex = mod.getArrangement()[currentArrangement]; currentPattern = mod.getPatternContainer().getPattern(currentPatternIndex); currentRow = 0; - initializeMixer(); if ((doNoLoops&ModConstants.PLAYER_LOOP_FADEOUT)!=0) doLoopingGlobalFadeout = true; } @@ -2263,14 +2261,16 @@ protected boolean doRowAndTickEvents() { currentRow = patternBreakRowIndex; patternBreakRowIndex = -1; - // If pattern break to position is set and last pattern reached, stay in last pattern + // If pattern break to position is set and last pattern reached, loop song and restart at given position, // but if loop_ignore is checked in params, don't do this. - //if (currentArrangement>=mod.getSongLength() && (doNoLoops&ModConstants.PLAYER_LOOP_IGNORE)==0) - //{ - // currentArrangement = mod.getSongLength()-1; - // if ((doNoLoops&ModConstants.PLAYER_LOOP_FADEOUT)!=0) - // doLoopingGlobalFadeout = true; - //} + if (currentArrangement>=mod.getSongLength() && (doNoLoops&ModConstants.PLAYER_LOOP_IGNORE)==0) + { + currentArrangement = mod.getSongRestart(); + currentPatternIndex = mod.getArrangement()[currentArrangement]; + currentPattern = mod.getPatternContainer().getPattern(currentPatternIndex); + if ((doNoLoops&ModConstants.PLAYER_LOOP_FADEOUT)!=0) + doLoopingGlobalFadeout = true; + } } else currentRow = 0; @@ -2363,7 +2363,7 @@ protected void fitIntoLoops(final ChannelMemory aktMemo) (inLoop == ModConstants.LOOP_SUSTAIN_ON && (sample.loopType & ModConstants.LOOP_SUSTAIN_IS_PINGPONG)!=0)) { aktMemo.isForwardDirection = false; - if ((mod.getModType()&ModConstants.MODTYPE_FASTTRACKER)!=0) // Protracker / XM need one less here! + if (isFastTracker) // Protracker / XM need one less here! aktMemo.currentSamplePos = loopEnd - aheadOfStop; else aktMemo.currentSamplePos = loopEnd - 1 - aheadOfStop; @@ -2412,6 +2412,7 @@ protected void fitIntoLoops(final ChannelMemory aktMemo) */ private void mixChannelIntoBuffers(final long[] leftBuffer, final long[] rightBuffer, final int startIndex, final int endIndex, final ChannelMemory aktMemo) { + aktMemo.bigSampleLeft = aktMemo.bigSampleRight = 0; for (int i=startIndex; iaktMemo.bigSampleLeft) aktMemo.bigSampleLeft = sampleL; + if (sampleR<0) sampleR = -sampleR; + if (sampleR>aktMemo.bigSampleRight) aktMemo.bigSampleRight = sampleR; + // Now next sample plus fit into loops - if any fitIntoLoops(aktMemo); @@ -2518,6 +2524,15 @@ public int mixIntoBuffer(final long[] leftBuffer, final long[] rightBuffer, fina // fill in those samples mixChannelIntoBuffers(leftBuffer, rightBuffer, startIndex, endIndex, aktMemo); + // This is only for eye-candy + if (!aktMemo.isNNA) + { + final boolean setZero = aktMemo.instrumentFinished || globalVolume==0 || masterVolume==0; + final long sampleL = (setZero)?0:((aktMemo.bigSampleLeft <<(7+((useGlobalPreAmp)?ModConstants.PREAMP_SHIFT-1:ModConstants.PREAMP_SHIFT))) / (long)globalVolume / (long)masterVolume)< -1) // aktive NNA-Channel + { + aktMemo.muted = channelMemory[aktMemo.channelNumber].muted; + } + } + } + /** + * Will mute/unmute a channel + * @since 27.11.2023 + * @param channelNumber + */ + public void toggleMuteChannel(final int channelNumber) + { + if (channelNumber>=0 && channelNumber<=maxChannels) + { + final ChannelMemory aktMemo = channelMemory[channelNumber]; + if (!aktMemo.wasITforced) aktMemo.muted = !aktMemo.muted; + setNNAMuteStatus(); + } + } + /** + * Unmutes all Channels, except, if IT wanted this channel to be muted! + * @since 27.11.2023 + */ + public void unMuteAll() + { + for (int c=0; c=0 && channelNumber<=maxChannels) + { + for (int c=0; c0 && element.getNoteIndex()>0)) aktMemo.portaTargetNotePeriod = getFineTunePeriod(aktMemo); if (aktMemo.effektParam!=0) aktMemo.portaNoteStep = aktMemo.effektParam; break; - case 0x04 : // Vibrato + case 0x04: // Vibrato if ((aktMemo.effektParam>>4)!=0) aktMemo.vibratoStep = aktMemo.effektParam>>4; if ((aktMemo.effektParam&0xF)!=0) aktMemo.vibratoAmplitude = aktMemo.effektParam&0xF; aktMemo.vibratoOn = true; break; - case 0x05 : // Porta To Note + VolumeSlide + case 0x05: // Porta To Note + VolumeSlide if (element!=null && (element.getPeriod()>0 && element.getNoteIndex()>0)) aktMemo.portaTargetNotePeriod = getFineTunePeriod(aktMemo); // With Protracker Mods Porta without Parameter is just Porta, no Vol-Slide if ((mod.getModType()&ModConstants.MODTYPE_MOD)!=0 && aktMemo.effektParam==0) @@ -183,7 +184,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.volumSlideValue = -(aktMemo.effektParam&0xF); } break; - case 0x06 : // Vibrato + VolumeSlide + case 0x06: // Vibrato + VolumeSlide aktMemo.vibratoOn = true; // With Protracker Mods Vibrato without Parameter is just Vibrato, no Vol-Slide if ((mod.getModType()&ModConstants.MODTYPE_MOD)!=0 && aktMemo.effektParam==0) @@ -197,27 +198,15 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.volumSlideValue = -(aktMemo.effektParam&0xF); } break; - case 0x07 : // Tremolo + case 0x07: // Tremolo if ((aktMemo.effektParam>>4)!=0) aktMemo.tremoloStep = aktMemo.effektParam>>4; if ((aktMemo.effektParam&0xF)!=0) aktMemo.tremoloAmplitude = aktMemo.effektParam&0xF; aktMemo.tremoloOn = true; break; - case 0x08 : // Set Panning + case 0x08: // Set Panning doPanning(aktMemo, aktMemo.effektParam, ModConstants.PanBits.Pan8Bit); break; case 0x09 : // Sample Offset -// if ((element.getPeriod()!=0 || element.getNoteIndex()!=0) && aktMemo.currentSample!=null) -// { -// if (aktMemo.effektParam!=0) -// { -// aktMemo.sampleOffset = aktMemo.highSampleOffset<<16 | aktMemo.effektParam<<8; -// aktMemo.highSampleOffset = 0; -// if (aktMemo.sampleOffset>=aktMemo.currentSample.length) -// aktMemo.sampleOffset = aktMemo.currentSample.length-1; -// } -// aktMemo.currentSamplePos = aktMemo.sampleOffset; -// aktMemo.isForwardDirection = true; aktMemo.currentTuningPos = 0; -// } if (aktMemo.effektParam!=0) { aktMemo.sampleOffset = aktMemo.highSampleOffset<<16 | aktMemo.effektParam<<8; @@ -236,7 +225,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.isForwardDirection = true; aktMemo.currentTuningPos = 0; } break; - case 0x0A : // Volume Slide + case 0x0A: // Volume Slide // With Protracker Mods Volumeslide without Parameter is not "old Parameter" if ((mod.getModType()&ModConstants.MODTYPE_MOD)!=0 && aktMemo.effektParam==0) aktMemo.volumSlideValue = 0; @@ -249,16 +238,16 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.volumSlideValue = -(aktMemo.effektParam&0xF); } break; - case 0x0B : // Pattern position jump + case 0x0B: // Pattern position jump patternBreakJumpPatternIndex = aktMemo.effektParam; break; - case 0x0C : // Set volume + case 0x0C: // Set volume aktMemo.savedCurrentVolume = aktMemo.currentVolume = aktMemo.effektParam; break; - case 0x0D : // Pattern break + case 0x0D: // Pattern break patternBreakRowIndex = ((aktMemo.effektParam>>4)*10)+(aktMemo.effektParam&0x0F); break; - case 0x0E : + case 0x0E: final int effektOp = aktMemo.effektParam&0x0F; switch (aktMemo.effektParam>>4) { @@ -286,7 +275,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.currentFinetuneFrequency = ModConstants.it_fineTuneTable[effektOp]; setNewPlayerTuningFor(aktMemo); break; - case 0x6 : // JumpLoop + case 0x6: // JumpLoop if (effektOp==0) // Set a marker for loop { aktMemo.jumpLoopPatternRow = currentRow; @@ -337,7 +326,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) if (aktMemo.currentVolume<0) aktMemo.currentVolume = 0; aktMemo.savedCurrentVolume = aktMemo.currentVolume; break; - case 0xC : // Note Cut + case 0xC: // Note Cut if (aktMemo.noteCutCount<0) { if (effektOp==0) // instant noteCut on first Tick @@ -346,7 +335,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.noteCutCount = effektOp; } break; - case 0xD : // Note Delay + case 0xD: // Note Delay if (aktMemo.noteDelayCount<0) // is done in BasicModMixer::doRowEvents { if (effektOp==0) @@ -355,7 +344,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.noteDelayCount = effektOp; } break; - case 0xE : // Pattern Delay --> # of Rows + case 0xE: // Pattern Delay --> # of Rows if (patternDelayCount<0) patternDelayCount=effektOp; // if currently in the patternDelay, do NOT reset the value. We would wait forever!!! break; case 0xF: // set MIDI Makro (ProTracker: Funk It!) @@ -363,8 +352,8 @@ protected void doRowEffects(final ChannelMemory aktMemo) break; } break; - case 0x0F : // SET SPEED - if (aktMemo.effektParam>31) // set bpm + case 0x0F: // SET SPEED / BPM + if (aktMemo.effektParam>31) // set BPM { currentBPM = aktMemo.effektParam; samplePerTicks = calculateSamplesPerTick(); @@ -372,33 +361,33 @@ protected void doRowEffects(final ChannelMemory aktMemo) else currentTick = currentTempo = aktMemo.effektParam; break; - case 0x10 : // Set global volume + case 0x10: // Set global volume globalVolume = (aktMemo.effektParam)<<1; if (globalVolume>128) globalVolume = 128; break; - case 0x11 : // Global volume slide + case 0x11: // Global volume slide if (aktMemo.effektParam!=0) aktMemo.globalVolumSlideValue = aktMemo.effektParam; break; - case 0x14 : // Key off + case 0x14: // Key off aktMemo.keyOffCounter = aktMemo.effektParam; break; - case 0x15 : // Set envelope position + case 0x15: // Set envelope position aktMemo.volEnvPos = aktMemo.effektParam; aktMemo.panEnvPos = aktMemo.effektParam; break; - case 0x19 : // Panning slide + case 0x19: // Panning slide if ((aktMemo.effektParam>>4)!=0) aktMemo.panningSlideValue = (aktMemo.effektParam>>4)<<2; else if ((aktMemo.effektParam&0xF)!=0) aktMemo.panningSlideValue = -((aktMemo.effektParam&0xF)<<2); break; - case 0x1B : // Multi retrig note + case 0x1B: // Multi retrig note if ((aktMemo.effektParam&0xF) !=0) aktMemo.retrigCount = aktMemo.retrigMemo = aktMemo.effektParam&0xF; if ((aktMemo.effektParam>>4)!=0) aktMemo.retrigVolSlide = aktMemo.effektParam>>4; doRetrigNote(aktMemo); break; - case 0x1D : // Tremor + case 0x1D: // Tremor if (aktMemo.effektParam!=0) { aktMemo.savedCurrentVolume = aktMemo.currentVolume; @@ -407,7 +396,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) } doTremorEffekt(aktMemo); break; - case 0x21 : // Extended XM Effects + case 0x21: // Extended XM Effects final int effektOpEx = aktMemo.effektParam&0x0F; switch (aktMemo.effektParam>>4) { @@ -463,7 +452,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) case 0xA: // Set High Offset aktMemo.highSampleOffset = aktMemo.effektParam&0x0F; break; - default : + default: Log.debug(String.format("Unknown Extended Effekt: Effect:%02X Op:%02X in [Pattern:%03d: Row:%03d Channel:%03d]", Integer.valueOf(aktMemo.effekt), Integer.valueOf(aktMemo.effektParam), Integer.valueOf(currentPatternIndex), Integer.valueOf(currentRow), Integer.valueOf(aktMemo.channelNumber+1))); break; } @@ -493,7 +482,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) processMIDIMacro(aktMemo, true, smoothMacro.getMidiZXXExt(aktMemo.effektParam & 0x7F), 0); } break; - default : + default: Log.debug(String.format("Unknown Effekt: Effect:%02X Op:%02X in [Pattern:%03d: Row:%03d Channel:%03d]", Integer.valueOf(aktMemo.effekt), Integer.valueOf(aktMemo.effektParam), Integer.valueOf(currentPatternIndex), Integer.valueOf(currentRow), Integer.valueOf(aktMemo.channelNumber+1))); break; } @@ -932,19 +921,15 @@ protected void doVolumeColumnRowEffekt(final ChannelMemory aktMemo) } } break; - case 0x0C: // Porta Down - if (aktMemo.volumeEffektOp!=0) aktMemo.portaStepDown = aktMemo.volumeEffektOp<<2; - break; - case 0x0D: // Porta Up - if (aktMemo.volumeEffektOp!=0) aktMemo.portaStepUp = aktMemo.volumeEffektOp<<2; +// case 0x0C: // Porta Down +// if (aktMemo.volumeEffektOp!=0) aktMemo.portaStepDown = aktMemo.volumeEffektOp<<2; +// break; +// case 0x0D: // Porta Up +// if (aktMemo.volumeEffektOp!=0) aktMemo.portaStepUp = aktMemo.volumeEffektOp<<2; +// break; + default: + Log.debug(String.format("Unknown VolEffekt: Effect:%02X Op:%02X in [Pattern:%03d: Row:%03d Channel:%03d]", Integer.valueOf(aktMemo.volumeEffekt), Integer.valueOf(aktMemo.volumeEffektOp), Integer.valueOf(currentPatternIndex), Integer.valueOf(currentRow), Integer.valueOf(aktMemo.channelNumber+1))); break; - case 0x0E: // Sample Cues - MPT specific -// final Sample sample = aktMemo.currentSample; -// if (sample!=null && sample.cues!=null && aktMemo.volumeEffektOp <= sample.cues.length) -// { -// if (aktMemo.volumeEffektOp!=0) aktMemo.sampleOffset = sample.cues[aktMemo.volumeEffektOp - 1]; -// doSampleOffsetEffekt(aktMemo, aktMemo.currentElement); -// } } } /** @@ -973,12 +958,12 @@ protected void doVolumeColumnTickEffekt(final ChannelMemory aktMemo) case 0x0B: // Tone Porta doPortaToNoteEffekt(aktMemo); break; - case 0x0C: // Porta Down - doPortaDown(aktMemo); - break; - case 0x0D: // Porta Up - doPortaUp(aktMemo); - break; +// case 0x0C: // Porta Down +// doPortaDown(aktMemo); +// break; +// case 0x0D: // Porta Up +// doPortaUp(aktMemo); +// break; } } /** @@ -1011,7 +996,6 @@ protected boolean isSampleOffsetEffekt(final int effekt) { return effekt==0x09; } - /** * @param aktMemo * @return @@ -1022,7 +1006,6 @@ protected boolean isNNAEffekt(final int effekt, final int effektParam) { return false; } - /** * @param aktMemo * @param effekt @@ -1035,4 +1018,112 @@ protected int getEffektOpMemory(final ChannelMemory aktMemo, final int effekt, f { return effektParam; } + /** + * @param effekt + * @param effektParam + * @return + * @see de.quippy.javamod.multimedia.mod.mixer.BasicModMixer#getEffectName(int, int) + */ + @Override + public String getEffectName(final int effekt, final int effektParam) + { + if (effekt==0 && effektParam==0) return Helpers.EMPTY_STING; + + switch (effekt) + { + case 0x00: return "Arpeggio"; + case 0x01: return "Porta Up"; + case 0x02: return "Porta Down"; + case 0x03: return "Porta To Note"; + case 0x04: return "Vibrato"; + case 0x05: return "PortaNote + VolSlide"; + case 0x06: return "Vibrato + VolSlide"; + case 0x07: return "Tremolo"; + case 0x08: return "Set Panning"; + case 0x09: return "Sample Offset"; + case 0x0A: return "Volume Slide"; + case 0x0B: return "Pattern Position Jump"; + case 0x0C: return "Set volume"; + case 0x0D: return "Pattern break"; + case 0x0E: + final int effektOp = effektParam&0x0F; + switch (effektParam>>4) + { + case 0x0: return "(!)Set filter(!)"; + case 0x1: return "Fine Porta Up"; + case 0x2: return "Fine Porta Down"; + case 0x3: return "Glissando"; + case 0x4: return "Set Vibrato Type"; + case 0x5: return "Set FineTune"; + case 0x6: if (effektOp==0) return "Jump Loop Set"; else return "Jump Loop"; + case 0x7: return "Set Tremolo Type"; + case 0x8: return "Set Fine Panning"; + case 0x9: return "Retrig Note"; + case 0xA: return "Fine Volume Up"; + case 0xB: return "Fine Volume Down"; + case 0xC: return "Note Cut"; + case 0xD: return "Note Delay"; + case 0xE: return "Pattern Delay"; + case 0xF: if ((mod.getModType()&ModConstants.MODTYPE_XM)!=0) return "Set MIDI Makro"; else return "Funk It!"; + } + break; + case 0x0F: if (effektParam>31) return "Set BPM"; else return "Set Speed"; + case 0x10: return "Set global volume"; + case 0x11: return "Global Volume Slide"; + case 0x14: return "Key off"; + case 0x15: return "Set Envelope Position"; + case 0x19: return "Panning Slide"; + case 0x1B: return "Retrig Note + VolSlide"; + case 0x1D: return "Tremor"; + case 0x21: // Extended XM Effects + switch (effektParam>>4) + { + case 0x1: return "Extra Fine Porta Up"; + case 0x2: return "Extra Fine Porta Down"; + case 0x5: return "set Panbrello Waveform"; + case 0x6: return "Fine Pattern Delay"; + case 0x9: // Sound Control + final int effektOpEx = effektParam&0x0F; + switch (effektOpEx) + { + case 0x0: return "No Surround"; + case 0x1: return "Enabl. Surround"; + } + break; + case 0xA: return "Set High Offset"; + } + break; + case 0x22: return "Panbrello"; + case 0x23: return "Midi Macro"; + case 0x24: return "Smooth Midi Macro"; + } + return "Unknown: " + Integer.toHexString(effekt) + "/" + Integer.toHexString(effektParam); + } + /** + * @param volumeEffekt + * @param volumeEffektOp + * @return + * @see de.quippy.javamod.multimedia.mod.mixer.BasicModMixer#getVolEffectName(int, int) + */ + @Override + public String getVolEffectName(final int volumeEffekt, final int volumeEffektOp) + { + if (volumeEffekt==0) return Helpers.EMPTY_STING; + + switch (volumeEffekt) + { + case 0x01: return "Set Volume"; + case 0x02: return "Volslide down"; + case 0x03: return "Volslide up"; + case 0x04: return "Fine Volslide Down"; + case 0x05: return "Fine Volslide Up"; + case 0x06: return "Set Vibrato Speed"; + case 0x07: if (volumeEffektOp!=0) return "Set Vibrato Depth"; else return "Vibrato"; + case 0x08: return "Set Panning"; + case 0x09: return "Panning Slide Left"; + case 0x0A: return "Panning Slide Right"; + case 0x0B: return "Porta To Note"; + } + return "Unknown: " + Integer.toHexString(volumeEffekt); + } } diff --git a/source/de/quippy/javamod/multimedia/mod/mixer/ScreamTrackerMixer.java b/source/de/quippy/javamod/multimedia/mod/mixer/ScreamTrackerMixer.java index 3c45553..f0460b4 100644 --- a/source/de/quippy/javamod/multimedia/mod/mixer/ScreamTrackerMixer.java +++ b/source/de/quippy/javamod/multimedia/mod/mixer/ScreamTrackerMixer.java @@ -28,6 +28,7 @@ import de.quippy.javamod.multimedia.mod.loader.instrument.Sample; import de.quippy.javamod.multimedia.mod.loader.pattern.PatternElement; import de.quippy.javamod.multimedia.mod.midi.MidiMacros; +import de.quippy.javamod.system.Helpers; import de.quippy.javamod.system.Log; /** @@ -58,7 +59,7 @@ protected void initializeMixer(int channel, ChannelMemory aktMemo) { if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) { - aktMemo.muted = ((mod.getPanningValue(channel) & 0x200)!=0); // 0x80<<2 + aktMemo.wasITforced = aktMemo.muted = ((mod.getPanningValue(channel) & 0x200)!=0); // 0x80<<2 aktMemo.doSurround = (mod.getPanningValue(channel) == 400); // 100<<2 - ist in der Tat kein HEX!!! } if ((mod.getSongFlags()&ModConstants.SONG_AMIGALIMITS)!=0) // S3M Amiga Limit flag @@ -137,24 +138,24 @@ protected void doRowEffects(final ChannelMemory aktMemo) switch (aktMemo.effekt) { - case 0x00: // no effect + case 0x00: // no effect, only effect OP is set break; - case 0x01 : // SET SPEED + case 0x01: // SET SPEED currentTick = currentTempo = aktMemo.effektParam; break; - case 0x02 : // Pattern position jump + case 0x02: // Pattern position jump patternBreakJumpPatternIndex = aktMemo.effektParam; break; - case 0x03 : // Pattern break + case 0x03: // Pattern break patternBreakRowIndex = aktMemo.effektParam&0xFF; break; - case 0x04 : // Volume Slide + case 0x04: // Volume Slide if (aktMemo.effektParam!=0) aktMemo.volumSlideValue = aktMemo.effektParam; // Fine Volume Up/Down and FastSlides if (isFineVolumeSlide(aktMemo.volumSlideValue) || (mod.getSongFlags()&ModConstants.SONG_FASTVOLSLIDES)!=0) doVolumeSlideEffekt(aktMemo); break; - case 0x05 : // Porta Down + case 0x05: // Porta Down if (aktMemo.effektParam!=0) { aktMemo.portaStepDown = aktMemo.effektParam; @@ -182,7 +183,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) setNewPlayerTuningFor(aktMemo); } break; - case 0x06 : // Porta Up + case 0x06: // Porta Up if (aktMemo.effektParam!=0) { aktMemo.portaStepUp=aktMemo.effektParam; @@ -210,7 +211,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) setNewPlayerTuningFor(aktMemo); } break; - case 0x07 : // Porta To Note + case 0x07: // Porta To Note if (element!=null && (element.getPeriod()>0 && element.getNoteIndex()>0)) aktMemo.portaTargetNotePeriod = getFineTunePeriod(aktMemo); if (aktMemo.effektParam!=0) { @@ -218,13 +219,13 @@ protected void doRowEffects(final ChannelMemory aktMemo) if ((mod.getSongFlags() & ModConstants.SONG_ITCOMPATMODE)==0) aktMemo.IT_EFG = aktMemo.portaNoteStep; } break; - case 0x08 : // Vibrato + case 0x08: // Vibrato if ((aktMemo.effektParam>>4)!=0) aktMemo.vibratoStep = aktMemo.effektParam>>4; if ((aktMemo.effektParam&0xF)!=0) aktMemo.vibratoAmplitude = (aktMemo.effektParam&0xF)<<2; aktMemo.vibratoOn = true; if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) doVibratoEffekt(aktMemo, false); // IT: on first TICK break; - case 0x09 : // Tremor + case 0x09: // Tremor if (aktMemo.effektParam!=0) { aktMemo.savedCurrentVolume = aktMemo.currentVolume; @@ -240,7 +241,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) if (aktMemo.tremorOfftimeSet==0) aktMemo.tremorOfftimeSet=1; doTremorEffekt(aktMemo); break; - case 0x0A : // Arpeggio + case 0x0A: // Arpeggio if (aktMemo.effektParam != 0) aktMemo.arpegioParam = aktMemo.effektParam; if (aktMemo.assignedNotePeriod!=0) { @@ -257,31 +258,31 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.arpegioIndex=0; } break; - case 0x0B : // Vibrato + Volume Slide + case 0x0B: // Vibrato + Volume Slide aktMemo.vibratoOn = true; if (aktMemo.effektParam!=0) aktMemo.volumSlideValue = aktMemo.effektParam; // Fine Volume Up/Down and FastSlides if (isFineVolumeSlide(aktMemo.volumSlideValue) || (mod.getSongFlags()&ModConstants.SONG_FASTVOLSLIDES)!=0) doVolumeSlideEffekt(aktMemo); break; - case 0x0C : // Porta To Note + VolumeSlide + case 0x0C: // Porta To Note + VolumeSlide if (element!=null && (element.getPeriod()>0 && element.getNoteIndex()>0)) aktMemo.portaTargetNotePeriod = getFineTunePeriod(aktMemo); if (aktMemo.effektParam!=0) aktMemo.volumSlideValue = aktMemo.effektParam; // Fine Volume Up/Down and FastSlides if (isFineVolumeSlide(aktMemo.volumSlideValue) || (mod.getSongFlags()&ModConstants.SONG_FASTVOLSLIDES)!=0) doVolumeSlideEffekt(aktMemo); break; - case 0x0D : // Set Channel Volume + case 0x0D: // Set Channel Volume aktMemo.channelVolume = aktMemo.effektParam; if (aktMemo.channelVolume>64) aktMemo.channelVolume = 64; break; - case 0x0E : // Channel Volume Slide + case 0x0E: // Channel Volume Slide if (aktMemo.effektParam!=0) aktMemo.channelVolumSlideValue = aktMemo.effektParam; // Fine Volume Up/Down and FastSlides if (isFineVolumeSlide(aktMemo.channelVolumSlideValue) || (mod.getSongFlags()&ModConstants.SONG_FASTVOLSLIDES)!=0) doChannelVolumeSlideEffekt(aktMemo); break; - case 0x0F : // Sample Offset + case 0x0F: // Sample Offset if (aktMemo.effektParam!=0) { aktMemo.sampleOffset = aktMemo.highSampleOffset<<16 | aktMemo.effektParam<<8; @@ -289,7 +290,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) } doSampleOffsetEffekt(aktMemo, element); break; - case 0x10 : // Panning Slide + case 0x10: // Panning Slide if (aktMemo.effektParam!=0) { if ((aktMemo.effektParam>>4)!=0) @@ -306,12 +307,12 @@ protected void doRowEffects(final ChannelMemory aktMemo) } doRetrigNote(aktMemo, false); break; - case 0x12 : // Tremolo + case 0x12: // Tremolo if ((aktMemo.effektParam>>4)!=0) aktMemo.tremoloStep = aktMemo.effektParam>>4; if ((aktMemo.effektParam&0xF)!=0) aktMemo.tremoloAmplitude = aktMemo.effektParam&0xF; aktMemo.tremoloOn = true; break; - case 0x13 : // Extended + case 0x13: // Extended final int effektParam = (aktMemo.effektParam==0) ? aktMemo.S_Effect_Memory : (aktMemo.S_Effect_Memory=aktMemo.effektParam); final int effektOpEx = effektParam&0x0F; switch (effektParam>>4) @@ -345,7 +346,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) case 0x0: // Note Cut all NNAs of this channel doNNAforAllof(aktMemo, ModConstants.NNA_CUT); break; - case 0x1: // Note Off NNAs of this channel + case 0x1: // Note Off all NNAs of this channel doNNAforAllof(aktMemo, ModConstants.NNA_OFF); break; case 0x2: // Note Fade all NNAs of this channel @@ -445,7 +446,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) case 0xA: // set High Offset aktMemo.highSampleOffset = effektOpEx; break; - case 0xB : // JumpLoop + case 0xB: // JumpLoop if (effektOpEx==0) // Set a marker for loop { aktMemo.jumpLoopPatternRow = currentRow; @@ -476,7 +477,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) } } break; - case 0xC : // Note Cut + case 0xC: // Note Cut if (aktMemo.noteCutCount<0) { if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) @@ -494,7 +495,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.noteCutCount = effektOpEx; } break; - case 0xD : // Note Delay + case 0xD: // Note Delay if (aktMemo.noteDelayCount<0) // is done in BasicModMixer::doRowEvents { if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) @@ -512,7 +513,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.noteDelayCount = effektOpEx; } break; - case 0xE : // Pattern Delay - if currently in the patternDelay, do NOT reset the value. We would wait forever!!! + case 0xE: // Pattern Delay - if currently in the patternDelay, do NOT reset the value. We would wait forever!!! if (patternDelayCount<0) patternDelayCount=effektOpEx; break; case 0xF: // Set Active Macro (s3m: Funk Repeat) @@ -523,7 +524,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) break; } break; - case 0x14 : // set Tempo + case 0x14: // set Tempo if (aktMemo.effektParam>>4==0) // 0x0X currentBPM -= aktMemo.effektParam&0xF; else @@ -533,7 +534,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) currentBPM = aktMemo.effektParam; // 0x2X samplePerTicks = calculateSamplesPerTick(); break; - case 0x15 : // Fine Vibrato + case 0x15: // Fine Vibrato // This effect is identical to the vibrato, but has a 4x smaller amplitude (more precise). if ((aktMemo.effektParam>>4)!=0) aktMemo.vibratoStep = aktMemo.effektParam>>4; if ((aktMemo.effektParam&0xF)!=0) @@ -545,7 +546,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) aktMemo.vibratoOn = true; if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) doVibratoEffekt(aktMemo, true); // IT: on first TICK break; - case 0x16 : // Set Global Volume + case 0x16: // Set Global Volume if (aktMemo.effektParam<=0x80) { globalVolume = aktMemo.effektParam; @@ -557,15 +558,15 @@ protected void doRowEffects(final ChannelMemory aktMemo) } } break; - case 0x17 : // Global Volume Slide + case 0x17: // Global Volume Slide if (aktMemo.effektParam!=0) aktMemo.globalVolumSlideValue = aktMemo.effektParam; if (isFineVolumeSlide(aktMemo.globalVolumSlideValue)) doGlobalVolumeSlideEffekt(aktMemo); break; - case 0x18 : // Set Panning + case 0x18: // Set Panning doPanning(aktMemo, aktMemo.effektParam, ModConstants.PanBits.Pan8Bit); break; - case 0x19 : // Panbrello + case 0x19: // Panbrello if ((aktMemo.effektParam>>4)!=0) aktMemo.panbrelloStep = aktMemo.effektParam>>4; if ((aktMemo.effektParam&0xF)!=0) aktMemo.panbrelloAmplitude = aktMemo.effektParam&0xF; aktMemo.panbrelloOn = true; @@ -590,7 +591,7 @@ protected void doRowEffects(final ChannelMemory aktMemo) processMIDIMacro(aktMemo, true, smoothMacro.getMidiZXXExt(aktMemo.effektParam & 0x7F), 0); } break; - default : + default: Log.debug(String.format("Unknown Effekt: Effect:%02X Op:%02X in [Pattern:%03d: Row:%03d Channel:%03d]", Integer.valueOf(aktMemo.effekt), Integer.valueOf(aktMemo.effektParam), Integer.valueOf(currentPatternIndex), Integer.valueOf(currentRow), Integer.valueOf(aktMemo.channelNumber+1))); break; } @@ -1314,13 +1315,16 @@ protected void doVolumeColumnRowEffekt(final ChannelMemory aktMemo) if ((mod.getSongFlags() & ModConstants.SONG_ITCOMPATMODE)==0) aktMemo.IT_EFG = aktMemo.portaStepUp; } break; - case 0x0E: // Sample Cues - MPT specific +// case 0x0E: // Sample Cues - MPT specific // final Sample sample = aktMemo.currentSample; // if (sample!=null && sample.cues!=null && aktMemo.volumeEffektOp <= sample.cues.length) // { // if (aktMemo.volumeEffektOp!=0) aktMemo.sampleOffset = sample.cues[aktMemo.volumeEffektOp - 1]; // doSampleOffsetEffekt(aktMemo, aktMemo.currentElement); // } +// break; + default: + Log.debug(String.format("Unknown VolEffekt: Effect:%02X Op:%02X in [Pattern:%03d: Row:%03d Channel:%03d]", Integer.valueOf(aktMemo.volumeEffekt), Integer.valueOf(aktMemo.volumeEffektOp), Integer.valueOf(currentPatternIndex), Integer.valueOf(currentRow), Integer.valueOf(aktMemo.channelNumber+1))); break; } } @@ -1412,4 +1416,126 @@ protected int getEffektOpMemory(final ChannelMemory aktMemo, final int effekt, i if (effekt==0x13 && effektParam == 0) return aktMemo.S_Effect_Memory; return effektParam; } + /** + * @param effekt + * @param effektParam + * @return + * @see de.quippy.javamod.multimedia.mod.mixer.BasicModMixer#getEffectName(int, int) + */ + @Override + public String getEffectName(final int effekt, final int effektParam) + { + if (effekt==0 && effektParam==0) return Helpers.EMPTY_STING; + + switch (effekt) + { + case 0x00: return "only OP set(!)"; + case 0x01: return "Set Speed"; + case 0x02: return "Pattern Position Jump"; + case 0x03: return "Pattern break"; + case 0x04: return "Volume Slide"; + case 0x05: return "Porta Down"; + case 0x06: return "Porta Up"; + case 0x07: return "Porta To Note"; + case 0x08: return "Vibrato"; + case 0x09: return "Tremor"; + case 0x0A: return "Arpeggio"; + case 0x0B: return "Vibrato + VolSlide"; + case 0x0C: return "PortaNote + VolSlide"; + case 0x0D: return "Set Volume"; + case 0x0E: return "Volume Slide"; + case 0x0F: return "Sample Offset"; + case 0x10: return "Panning Slide"; + case 0x11: return "Retrig Note"; + case 0x12: return "Tremolo"; + case 0x13 : // Extended + final int effektOpEx = effektParam&0x0F; + switch (effektParam>>4) + { + case 0x1: return "Glissando"; + case 0x2: return "Set FineTune"; + case 0x3: return "Set Vibrato Type"; + case 0x4: return "Set Tremolo Type"; + case 0x5: return "Set Panbrello Type"; + case 0x6: return "Pattern Delay Frame"; + case 0x7: // set NNA and others + switch (effektOpEx) + { + case 0x0: return "Note Cut all NNAs"; + case 0x1: return "Note Off all NNAs"; + case 0x2: return "Note Fade all NNAs"; + case 0x3: return "NNA Cut"; + case 0x4: return "NNA Continue"; + case 0x5: return "NNA Off"; + case 0x6: return "NNA Fade"; + case 0x7: return "Volume Envelope Off"; + case 0x8: return "Volume Envelope On"; + case 0x9: return "Panning Envelope Off"; + case 0xA: return "Panning Envelope On"; + case 0xB: return "Pitch Envelope Off"; + case 0xC: return "Pitch Envelope On"; + } + break; + case 0x8: return "Set Fine Panning"; + case 0x9: // Sound Control + switch (effektOpEx) + { + case 0x0: return "No Surround"; + case 0x1: return "Enabl. Surround"; + } + break; + case 0xA: return "Set High Offset"; + case 0xB: if (effektOpEx==0) return "Jump Loop Set"; else return "Jump Loop"; + case 0xC: return "Note Cut"; + case 0xD: return "Note Delay"; + case 0xE: return "Pattern Delay"; + case 0xF: if ((mod.getModType()&ModConstants.MODTYPE_IT)!=0) return "Set Active Macro"; else return "Funk Repeat"; + } + break; + case 0x14: + if (effektParam>>4==0) // 0x0X + return "Set BPM (slower)"; + else + if (effektParam>>4==1) // 0x1X + return "Set BPM (faster)"; + else + return "Set BPM"; // 0x2X + case 0x15: return "Fine Vibrato"; + case 0x16: return "Set Global Volume"; + case 0x17: return "Global Volume Slide"; + case 0x18: return "Set Panning"; + case 0x19: return "Panbrello"; + case 0x1A: return "Midi Macro"; + case 0x1C: return "Smooth Midi Macro"; + } + return "Unknown: " + Integer.toHexString(effekt) + "/" + Integer.toHexString(effektParam); + } + /** + * @param volumeEffekt + * @param volumeEffektOp + * @return + * @see de.quippy.javamod.multimedia.mod.mixer.BasicModMixer#getVolEffectName(int, int) + */ + @Override + public String getVolEffectName(final int volumeEffekt, final int volumeEffektOp) + { + if (volumeEffekt==0) return Helpers.EMPTY_STING; + + switch (volumeEffekt) + { + case 0x01: return "Set Volume"; + case 0x02: return "Volslide down"; + case 0x03: return "Volslide up"; + case 0x04: return "Fine Volslide Down"; + case 0x05: return "Fine Volslide Up"; + case 0x07: if (volumeEffektOp!=0) return "Set Vibrato Depth"; else return "Vibrato"; + case 0x08: return "Set Panning"; + case 0x09: return "Panning Slide Left"; + case 0x0A: return "Panning Slide Right"; + case 0x0B: return "Porta To Note"; + case 0x0C: return "Porta Down"; + case 0x0D: return "Porta Up"; + } + return "Unknown: " + Integer.toHexString(volumeEffekt); + } } diff --git a/source/de/quippy/javamod/system/CircularBuffer.java b/source/de/quippy/javamod/system/CircularBuffer.java index 906e42d..c1a8ed0 100644 --- a/source/de/quippy/javamod/system/CircularBuffer.java +++ b/source/de/quippy/javamod/system/CircularBuffer.java @@ -25,16 +25,16 @@ /** * I was not able to find a standard FIFO stack implementation that would not - * grow, so I made my own very basic implementation. + * grow automatically, so I made my own very basic implementation.
* This implementation will not grow. If the size is not sufficient, no more - * pushes will be possible. + * pushes will be possible. However, you can in that case call "growBy".
* The PushPointer always points to the next empty entry, the popPointer to - * the next element to be popped. - * It is defined empty, when Push and Pull are on the same Index. It is defined - * full, when the pushPointer + 1 would fall on popPointer. - * That means, that we can only fill (size - 1) elements into the queue. - * This implementation is not thread-safe, but we do want to be fast - so no - * synchronized blocks or method. Give it a bit of safety by declaring vars + * the next element to be popped. With peek you can do a look-ahead.
+ * It is defined empty, when push- and popPointer are on the same Index. It is defined + * full, when the pushPointer + 1 would fall on popPointer.
+ * That means, that we can only fill (size - 1) elements into the queue.

+ * This implementation is not thread-safe, but we do want to be fast - so no + * synchronized blocks or method. Giving it a bit of safety by declaring vars * as volatile. * @author Daniel Becker * @since 13.11.2023 @@ -55,7 +55,7 @@ public CircularBuffer(final int capacity) { super(); elements = new Object[size = capacity]; - flush(); + popPointer = pushPointer = 0; } /** * Constructor for CircularBuffer with a default of 64 elements @@ -73,6 +73,36 @@ public int getBufferSize() { return size; } + /** + * We will resize the buffer by either adding new space at the end (i.e. pushPointer + * is greater or equal to popPointer) or we will enlarge the space between + * push- and popPointer.
+ * This operation is not thread safe! If one thread pushes or resizes and another one + * is popping, this will result in unforseeable results. + * @since 02.12.2023 + * @param addSize + */ + public void growBy(final int addSize) + { + Object [] newBuffer = new Object[size + addSize]; + + if (pushPointer >= popPointer) // just add new space at the end + { + System.arraycopy(elements, 0, newBuffer, 0, size); + } + else // enlarge space between push- and popPointer + { + // copy pop-able elements to the end + final int popElementsTillWrap = size - popPointer; + final int newPopPointer = newBuffer.length-popElementsTillWrap; + System.arraycopy(elements, popPointer, newBuffer, newPopPointer, popElementsTillWrap); + popPointer = newPopPointer; + // and copy the rest to the front + System.arraycopy(elements, 0, newBuffer, 0, pushPointer); + } + elements = newBuffer; + size = elements.length; + } /** * Returns the amount of elements queued. * @since 13.11.2023 @@ -89,7 +119,7 @@ public int getSize() */ public int getFree() { - return (pushPointer>=popPointer) ? size - pushPointer - popPointer - 1 : popPointer - pushPointer; + return (pushPointer>=popPointer) ? size - pushPointer + popPointer - 1 : popPointer - pushPointer - 1; } /** * Flush the buffer - i.e. pushPointer and popPointer are set to zero @@ -128,11 +158,12 @@ public E pop() if (isEmpty()) return null; E element = (E)elements[popPointer]; + elements[popPointer] = null; // delete the popped element popPointer = (popPointer + 1) % size; return element; } /** - * Look ahead for plus add on pushPointer. Add can be 0 to peek the current + * Look ahead for popPointer plus "add" elements. "add" can be 0 to peek the current * "pop-able" value. * If the queue contains any value, the whole list can be iterated, even * beyond pushPointer. No checks done. @@ -148,7 +179,8 @@ public E peek(final int add) return (E)elements[(popPointer + add) % size]; } /** - * Add an element. So far, if there is no space left, we will do nothing + * Add an element. If there is no space left, we will do nothing. You may + * check that in advance and call "growBy" to add more space. * @since 13.11.2023 * @param element */ @@ -159,4 +191,31 @@ public void push(E element) elements[pushPointer] = element; pushPointer = (pushPointer + 1) % size; } + /** + * Give us a String representation of this Object. That is:
+ * pushPointer / popPointer
+ * # values queued / # free space
+ * the pushed elements (max 10 of them) + * @return A String representation of this Queue + * @see java.lang.Object#toString() + */ + public String toString() + { + StringBuffer sb = new StringBuffer('{'); + sb.append(String.valueOf(pushPointer)).append('/').append(String.valueOf(popPointer)).append(',') + .append(String.valueOf(getSize())).append('/').append(String.valueOf(getFree())) + .append(", {"); + if (elements==null) sb.append("NULL"); + else + { + final int printMe = (size<10)?size:10; + for (int i=0; i0) sb.append(','); + if (elements[i]==null) sb.append("NULL"); else sb.append(elements[i].toString()); + } + if (size>printMe) sb.append(",..."); + } + return sb.append("}}").toString(); + } } diff --git a/source/de/quippy/javamod/system/Helpers.java b/source/de/quippy/javamod/system/Helpers.java index fb8fb43..53c3fab 100644 --- a/source/de/quippy/javamod/system/Helpers.java +++ b/source/de/quippy/javamod/system/Helpers.java @@ -29,6 +29,7 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; @@ -87,7 +88,7 @@ private Helpers() } /** Version Information */ - public static final String VERSION = "V3.6"; + public static final String VERSION = "V3.7"; public static final String PROGRAM = "Java Mod Player"; public static final String FULLVERSION = PROGRAM+' '+VERSION; public static final String COPYRIGHT = "© by Daniel Becker since 2006"; @@ -100,7 +101,7 @@ private Helpers() /** Codepages used when reading mod files */ public static final String CODING_GUI = "cp850"; public static final String CODING_COMMANLINE = "cp1252"; - /** Default value - changes whether SWING or commandline */ + /** Default value - changes whether SWING or command line */ public static String currentCoding = CODING_GUI; /** Codepages used when reading playlist files */ public static final String CODING_M3U = "ISO-8859-1"; @@ -334,7 +335,8 @@ public static String getHTMLColorString(Color color) if (htmlColor.length()>6) htmlColor = htmlColor.substring(htmlColor.length() - 6); return htmlColor; } - private static java.awt.Insets DEFAULT_INSETS = new java.awt.Insets(4, 4, 4, 4); + private static Insets DEFAULT_INSETS = new Insets(4, 4, 4, 4); + public static Insets NULL_INSETS = new Insets(0,0,0,0); /** * @since 22.06.2006 * @param gridx @@ -347,7 +349,7 @@ public static String getHTMLColorString(Color color) * @param weighty * @return */ - public static java.awt.GridBagConstraints getGridBagConstraint(final int gridx, final int gridy, final int gridheight, final int gridwidth, final int fill, final int anchor, final double weightx, final double weighty) + public static GridBagConstraints getGridBagConstraint(final int gridx, final int gridy, final int gridheight, final int gridwidth, final int fill, final int anchor, final double weightx, final double weighty) { return getGridBagConstraint(gridx, gridy, gridheight, gridwidth, fill, anchor, weightx, weighty, DEFAULT_INSETS); } @@ -364,9 +366,9 @@ public static java.awt.GridBagConstraints getGridBagConstraint(final int gridx, * @param insets * @return */ - public static java.awt.GridBagConstraints getGridBagConstraint(final int gridx, final int gridy, final int gridheight, final int gridwidth, final int fill, final int anchor, final double weightx, final double weighty, final Insets insets) + public static GridBagConstraints getGridBagConstraint(final int gridx, final int gridy, final int gridheight, final int gridwidth, final int fill, final int anchor, final double weightx, final double weighty, final Insets insets) { - java.awt.GridBagConstraints constraints = new java.awt.GridBagConstraints(); + GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = gridx; constraints.gridy = gridy; constraints.gridheight = gridheight; @@ -502,16 +504,16 @@ public static List readLinesFromFlavor(BufferedReader bReader) public static List getDropData(DropTargetDropEvent dtde) { List files = null; + boolean handled = false; try { - final Transferable t = dtde.getTransferable(); - if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) + final Transferable transferable = dtde.getTransferable(); + if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor) && (dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE)!=0) { - boolean handled = false; - dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); + dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); // Check, if we have a flavor to read manually from - DataFlavor[] flavors = t.getTransferDataFlavors(); + DataFlavor[] flavors = transferable.getTransferDataFlavors(); for (int flv=0; flv getDropData(DropTargetDropEvent dtde) // KDE BUG: check for flavors to manually read from if (flavor.isRepresentationClassReader()) { - Reader reader = flavor.getReaderForText(t); + Reader reader = flavor.getReaderForText(transferable); files = Helpers.readLinesFromFlavor(new BufferedReader(reader)); handled = true; // we are already satisfied } } if (!handled) // no readable flavor was found - use the javaFileListFlavor { - final Object userObject = t.getTransferData(DataFlavor.javaFileListFlavor); + final Object userObject = transferable.getTransferData(DataFlavor.javaFileListFlavor); if (userObject!=null && userObject instanceof List) { files = ((List)userObject); handled = true; } } - if (!handled) dtde.rejectDrop(); } + else + dtde.rejectDrop(); } catch (Throwable ex) { - Log.error("Helpers:handleDrop", ex); + Log.error("Helpers::handleDrop", ex); } finally { - dtde.dropComplete(true); + dtde.dropComplete(handled); } return files; } diff --git a/source/de/quippy/jmac/decoder/APEDecompress.java b/source/de/quippy/jmac/decoder/APEDecompress.java index eb9c62a..d67dfbf 100644 --- a/source/de/quippy/jmac/decoder/APEDecompress.java +++ b/source/de/quippy/jmac/decoder/APEDecompress.java @@ -19,13 +19,22 @@ package de.quippy.jmac.decoder; -import de.quippy.jmac.info.*; +import java.io.IOException; + +import de.quippy.jmac.info.APEFileInfo; +import de.quippy.jmac.info.APEInfo; +import de.quippy.jmac.info.APETag; +import de.quippy.jmac.info.SpecialFrame; +import de.quippy.jmac.info.WaveFormat; +import de.quippy.jmac.info.WaveHeader; import de.quippy.jmac.prediction.IPredictorDecompress; import de.quippy.jmac.prediction.PredictorDecompress3950toCurrent; import de.quippy.jmac.prediction.PredictorDecompressNormal3930to3950; -import de.quippy.jmac.tools.*; - -import java.io.IOException; +import de.quippy.jmac.tools.CircleBuffer; +import de.quippy.jmac.tools.Crc32; +import de.quippy.jmac.tools.File; +import de.quippy.jmac.tools.JMACException; +import de.quippy.jmac.tools.Prepare; /** * Author: Dmitry Vaguine diff --git a/source/de/quippy/jmac/decoder/APEDecompressCore.java b/source/de/quippy/jmac/decoder/APEDecompressCore.java index 2b92260..d644540 100644 --- a/source/de/quippy/jmac/decoder/APEDecompressCore.java +++ b/source/de/quippy/jmac/decoder/APEDecompressCore.java @@ -19,13 +19,13 @@ package de.quippy.jmac.decoder; +import java.io.IOException; +import java.util.Arrays; + import de.quippy.jmac.info.CompressionLevel; import de.quippy.jmac.info.SpecialFrame; import de.quippy.jmac.tools.JMACException; -import java.io.IOException; -import java.util.Arrays; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/decoder/APEDecompressOld.java b/source/de/quippy/jmac/decoder/APEDecompressOld.java index a861cc2..fffb01b 100644 --- a/source/de/quippy/jmac/decoder/APEDecompressOld.java +++ b/source/de/quippy/jmac/decoder/APEDecompressOld.java @@ -19,14 +19,18 @@ package de.quippy.jmac.decoder; -import de.quippy.jmac.info.*; +import java.io.IOException; +import java.util.Arrays; + +import de.quippy.jmac.info.APEFileInfo; +import de.quippy.jmac.info.APEInfo; +import de.quippy.jmac.info.APETag; +import de.quippy.jmac.info.WaveFormat; +import de.quippy.jmac.info.WaveHeader; import de.quippy.jmac.tools.ByteBuffer; import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; -import java.io.IOException; -import java.util.Arrays; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/decoder/UnBitArray.java b/source/de/quippy/jmac/decoder/UnBitArray.java index 5e8ae0c..482abc3 100644 --- a/source/de/quippy/jmac/decoder/UnBitArray.java +++ b/source/de/quippy/jmac/decoder/UnBitArray.java @@ -19,10 +19,10 @@ package de.quippy.jmac.decoder; -import de.quippy.jmac.tools.File; - import java.io.IOException; +import de.quippy.jmac.tools.File; + /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/decoder/UnBitArrayBase.java b/source/de/quippy/jmac/decoder/UnBitArrayBase.java index 83575ad..aeb7cf8 100644 --- a/source/de/quippy/jmac/decoder/UnBitArrayBase.java +++ b/source/de/quippy/jmac/decoder/UnBitArrayBase.java @@ -19,12 +19,12 @@ package de.quippy.jmac.decoder; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/decoder/UnMAC.java b/source/de/quippy/jmac/decoder/UnMAC.java index 619a207..b8f14f5 100644 --- a/source/de/quippy/jmac/decoder/UnMAC.java +++ b/source/de/quippy/jmac/decoder/UnMAC.java @@ -19,6 +19,8 @@ package de.quippy.jmac.decoder; +import java.io.IOException; + import de.quippy.jmac.info.APEHeader; import de.quippy.jmac.info.SpecialFrame; import de.quippy.jmac.info.WaveFormat; @@ -27,8 +29,6 @@ import de.quippy.jmac.tools.JMACException; import de.quippy.jmac.tools.Prepare; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/APEDescriptor.java b/source/de/quippy/jmac/info/APEDescriptor.java index e51dc25..b6c6fea 100644 --- a/source/de/quippy/jmac/info/APEDescriptor.java +++ b/source/de/quippy/jmac/info/APEDescriptor.java @@ -18,14 +18,14 @@ */ package de.quippy.jmac.info; +import java.io.EOFException; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.ByteArrayWriter; import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; -import java.io.EOFException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 07.04.2004 diff --git a/source/de/quippy/jmac/info/APEHeader.java b/source/de/quippy/jmac/info/APEHeader.java index 7238722..9b12418 100644 --- a/source/de/quippy/jmac/info/APEHeader.java +++ b/source/de/quippy/jmac/info/APEHeader.java @@ -19,13 +19,13 @@ package de.quippy.jmac.info; +import java.io.EOFException; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; -import java.io.EOFException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/APEHeaderNew.java b/source/de/quippy/jmac/info/APEHeaderNew.java index 8e52333..7bbb42b 100644 --- a/source/de/quippy/jmac/info/APEHeaderNew.java +++ b/source/de/quippy/jmac/info/APEHeaderNew.java @@ -19,14 +19,14 @@ package de.quippy.jmac.info; +import java.io.EOFException; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.ByteArrayWriter; import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; -import java.io.EOFException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/APEHeaderOld.java b/source/de/quippy/jmac/info/APEHeaderOld.java index 8b641e4..84e1e83 100644 --- a/source/de/quippy/jmac/info/APEHeaderOld.java +++ b/source/de/quippy/jmac/info/APEHeaderOld.java @@ -19,13 +19,13 @@ package de.quippy.jmac.info; +import java.io.EOFException; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; -import java.io.EOFException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/APEInfo.java b/source/de/quippy/jmac/info/APEInfo.java index 761ebc6..6ca120a 100644 --- a/source/de/quippy/jmac/info/APEInfo.java +++ b/source/de/quippy/jmac/info/APEInfo.java @@ -19,16 +19,16 @@ package de.quippy.jmac.info; -import de.quippy.jmac.tools.File; -import de.quippy.jmac.tools.InputStreamFile; -import de.quippy.jmac.tools.JMACException; -import de.quippy.jmac.tools.RandomAccessFile; - import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import de.quippy.jmac.tools.File; +import de.quippy.jmac.tools.InputStreamFile; +import de.quippy.jmac.tools.JMACException; +import de.quippy.jmac.tools.RandomAccessFile; + /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/APELink.java b/source/de/quippy/jmac/info/APELink.java index af48ab1..2fb65ca 100644 --- a/source/de/quippy/jmac/info/APELink.java +++ b/source/de/quippy/jmac/info/APELink.java @@ -19,12 +19,12 @@ package de.quippy.jmac.info; +import java.io.IOException; + import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; import de.quippy.jmac.tools.RandomAccessFile; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/APETagField.java b/source/de/quippy/jmac/info/APETagField.java index fddf229..2bd9f00 100644 --- a/source/de/quippy/jmac/info/APETagField.java +++ b/source/de/quippy/jmac/info/APETagField.java @@ -19,11 +19,11 @@ package de.quippy.jmac.info; +import java.io.UnsupportedEncodingException; + import de.quippy.jmac.tools.ByteArrayWriter; import de.quippy.jmac.tools.JMACException; -import java.io.UnsupportedEncodingException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/APETagFooter.java b/source/de/quippy/jmac/info/APETagFooter.java index 9617a87..c05c64c 100644 --- a/source/de/quippy/jmac/info/APETagFooter.java +++ b/source/de/quippy/jmac/info/APETagFooter.java @@ -19,14 +19,14 @@ package de.quippy.jmac.info; +import java.io.EOFException; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.ByteArrayWriter; import de.quippy.jmac.tools.File; import de.quippy.jmac.tools.JMACException; -import java.io.EOFException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/ID3Tag.java b/source/de/quippy/jmac/info/ID3Tag.java index 347295d..f063727 100644 --- a/source/de/quippy/jmac/info/ID3Tag.java +++ b/source/de/quippy/jmac/info/ID3Tag.java @@ -19,13 +19,13 @@ package de.quippy.jmac.info; +import java.io.EOFException; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.ByteArrayWriter; import de.quippy.jmac.tools.File; -import java.io.EOFException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/WaveFormat.java b/source/de/quippy/jmac/info/WaveFormat.java index 057d5af..dcfac9d 100644 --- a/source/de/quippy/jmac/info/WaveFormat.java +++ b/source/de/quippy/jmac/info/WaveFormat.java @@ -19,11 +19,11 @@ package de.quippy.jmac.info; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.File; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/info/WaveHeader.java b/source/de/quippy/jmac/info/WaveHeader.java index 4909e17..a1442d2 100644 --- a/source/de/quippy/jmac/info/WaveHeader.java +++ b/source/de/quippy/jmac/info/WaveHeader.java @@ -19,13 +19,13 @@ package de.quippy.jmac.info; +import java.io.EOFException; +import java.io.IOException; + import de.quippy.jmac.tools.ByteArrayReader; import de.quippy.jmac.tools.ByteArrayWriter; import de.quippy.jmac.tools.File; -import java.io.EOFException; -import java.io.IOException; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/prediction/NNFilter.java b/source/de/quippy/jmac/prediction/NNFilter.java index 0d6610f..7b64137 100644 --- a/source/de/quippy/jmac/prediction/NNFilter.java +++ b/source/de/quippy/jmac/prediction/NNFilter.java @@ -19,11 +19,11 @@ package de.quippy.jmac.prediction; +import java.util.Arrays; + import de.quippy.jmac.tools.JMACException; import de.quippy.jmac.tools.RollBufferShort; -import java.util.Arrays; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/prediction/PredictorDecompress3950toCurrent.java b/source/de/quippy/jmac/prediction/PredictorDecompress3950toCurrent.java index cbdddbf..2bef1ee 100644 --- a/source/de/quippy/jmac/prediction/PredictorDecompress3950toCurrent.java +++ b/source/de/quippy/jmac/prediction/PredictorDecompress3950toCurrent.java @@ -19,12 +19,12 @@ package de.quippy.jmac.prediction; +import java.util.Arrays; + import de.quippy.jmac.info.CompressionLevel; import de.quippy.jmac.tools.JMACException; import de.quippy.jmac.tools.RollBufferFastInt; -import java.util.Arrays; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/jmac/prediction/PredictorDecompressNormal3930to3950.java b/source/de/quippy/jmac/prediction/PredictorDecompressNormal3930to3950.java index 210887f..7234630 100644 --- a/source/de/quippy/jmac/prediction/PredictorDecompressNormal3930to3950.java +++ b/source/de/quippy/jmac/prediction/PredictorDecompressNormal3930to3950.java @@ -19,11 +19,11 @@ package de.quippy.jmac.prediction; +import java.util.Arrays; + import de.quippy.jmac.info.CompressionLevel; import de.quippy.jmac.tools.JMACException; -import java.util.Arrays; - /** * Author: Dmitry Vaguine * Date: 04.03.2004 diff --git a/source/de/quippy/ogg/jorbis/Block.java b/source/de/quippy/ogg/jorbis/Block.java old mode 100755 new mode 100644 index 2b6f62b..03d4858 --- a/source/de/quippy/ogg/jorbis/Block.java +++ b/source/de/quippy/ogg/jorbis/Block.java @@ -26,7 +26,8 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; +import de.quippy.ogg.jogg.Packet; public class Block{ ///necessary stream state for linking to the framing abstraction diff --git a/source/de/quippy/ogg/jorbis/CodeBook.java b/source/de/quippy/ogg/jorbis/CodeBook.java old mode 100755 new mode 100644 index 198b7df..29bd277 --- a/source/de/quippy/ogg/jorbis/CodeBook.java +++ b/source/de/quippy/ogg/jorbis/CodeBook.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; class CodeBook{ int dim; // codebook dimensions (elements per vector) diff --git a/source/de/quippy/ogg/jorbis/Comment.java b/source/de/quippy/ogg/jorbis/Comment.java old mode 100755 new mode 100644 index aa9c6af..c940ed5 --- a/source/de/quippy/ogg/jorbis/Comment.java +++ b/source/de/quippy/ogg/jorbis/Comment.java @@ -26,7 +26,8 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; +import de.quippy.ogg.jogg.Packet; // the comments are not part of vorbis_info so that vorbis_info can be // static storage diff --git a/source/de/quippy/ogg/jorbis/Floor0.java b/source/de/quippy/ogg/jorbis/Floor0.java old mode 100755 new mode 100644 index 4adcbf2..fddfd32 --- a/source/de/quippy/ogg/jorbis/Floor0.java +++ b/source/de/quippy/ogg/jorbis/Floor0.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; class Floor0 extends FuncFloor{ diff --git a/source/de/quippy/ogg/jorbis/Floor1.java b/source/de/quippy/ogg/jorbis/Floor1.java old mode 100755 new mode 100644 index 6841547..6973bd8 --- a/source/de/quippy/ogg/jorbis/Floor1.java +++ b/source/de/quippy/ogg/jorbis/Floor1.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; class Floor1 extends FuncFloor{ static final int floor1_rangedb=140; diff --git a/source/de/quippy/ogg/jorbis/FuncFloor.java b/source/de/quippy/ogg/jorbis/FuncFloor.java old mode 100755 new mode 100644 index 61b6257..2efc2a5 --- a/source/de/quippy/ogg/jorbis/FuncFloor.java +++ b/source/de/quippy/ogg/jorbis/FuncFloor.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; abstract class FuncFloor{ diff --git a/source/de/quippy/ogg/jorbis/FuncMapping.java b/source/de/quippy/ogg/jorbis/FuncMapping.java old mode 100755 new mode 100644 index 73ee1fc..39c6815 --- a/source/de/quippy/ogg/jorbis/FuncMapping.java +++ b/source/de/quippy/ogg/jorbis/FuncMapping.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; abstract class FuncMapping{ public static FuncMapping[] mapping_P= {new Mapping0()}; diff --git a/source/de/quippy/ogg/jorbis/FuncResidue.java b/source/de/quippy/ogg/jorbis/FuncResidue.java old mode 100755 new mode 100644 index bc0d9d2..fa15b5c --- a/source/de/quippy/ogg/jorbis/FuncResidue.java +++ b/source/de/quippy/ogg/jorbis/FuncResidue.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; abstract class FuncResidue{ public static FuncResidue[] residue_P= {new Residue0(), new Residue1(), diff --git a/source/de/quippy/ogg/jorbis/FuncTime.java b/source/de/quippy/ogg/jorbis/FuncTime.java old mode 100755 new mode 100644 index 8b6be60..5797fca --- a/source/de/quippy/ogg/jorbis/FuncTime.java +++ b/source/de/quippy/ogg/jorbis/FuncTime.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; abstract class FuncTime{ public static FuncTime[] time_P= {new Time0()}; diff --git a/source/de/quippy/ogg/jorbis/Info.java b/source/de/quippy/ogg/jorbis/Info.java old mode 100755 new mode 100644 index 8611f6d..cfe8b62 --- a/source/de/quippy/ogg/jorbis/Info.java +++ b/source/de/quippy/ogg/jorbis/Info.java @@ -26,7 +26,8 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; +import de.quippy.ogg.jogg.Packet; public class Info{ private static final int OV_EBADPACKET=-136; diff --git a/source/de/quippy/ogg/jorbis/Mapping0.java b/source/de/quippy/ogg/jorbis/Mapping0.java old mode 100755 new mode 100644 index 33c9040..b19ffff --- a/source/de/quippy/ogg/jorbis/Mapping0.java +++ b/source/de/quippy/ogg/jorbis/Mapping0.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; class Mapping0 extends FuncMapping{ static int seq=0; diff --git a/source/de/quippy/ogg/jorbis/Residue0.java b/source/de/quippy/ogg/jorbis/Residue0.java old mode 100755 new mode 100644 index 35efe6a..6df3800 --- a/source/de/quippy/ogg/jorbis/Residue0.java +++ b/source/de/quippy/ogg/jorbis/Residue0.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; class Residue0 extends FuncResidue{ void pack(Object vr, Buffer opb){ diff --git a/source/de/quippy/ogg/jorbis/StaticCodeBook.java b/source/de/quippy/ogg/jorbis/StaticCodeBook.java old mode 100755 new mode 100644 index 96aed1c..8a0cc9d --- a/source/de/quippy/ogg/jorbis/StaticCodeBook.java +++ b/source/de/quippy/ogg/jorbis/StaticCodeBook.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; class StaticCodeBook{ int dim; // codebook dimensions (elements per vector) diff --git a/source/de/quippy/ogg/jorbis/Time0.java b/source/de/quippy/ogg/jorbis/Time0.java old mode 100755 new mode 100644 index ed97027..d1e65a0 --- a/source/de/quippy/ogg/jorbis/Time0.java +++ b/source/de/quippy/ogg/jorbis/Time0.java @@ -26,7 +26,7 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; +import de.quippy.ogg.jogg.Buffer; class Time0 extends FuncTime{ void pack(Object i, Buffer opb){ diff --git a/source/de/quippy/ogg/jorbis/VorbisFile.java b/source/de/quippy/ogg/jorbis/VorbisFile.java old mode 100755 new mode 100644 index 0fa2ac7..eb79a04 --- a/source/de/quippy/ogg/jorbis/VorbisFile.java +++ b/source/de/quippy/ogg/jorbis/VorbisFile.java @@ -27,10 +27,13 @@ package de.quippy.ogg.jorbis; -import de.quippy.ogg.jogg.*; - -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; + +import de.quippy.ogg.jogg.Packet; +import de.quippy.ogg.jogg.Page; +import de.quippy.ogg.jogg.StreamState; +import de.quippy.ogg.jogg.SyncState; public class VorbisFile{ static final int CHUNKSIZE=8500; diff --git a/source/de/quippy/sidplay/libsidplay/Player.java b/source/de/quippy/sidplay/libsidplay/Player.java index 531d602..b3412e4 100644 --- a/source/de/quippy/sidplay/libsidplay/Player.java +++ b/source/de/quippy/sidplay/libsidplay/Player.java @@ -76,18 +76,19 @@ import static de.quippy.sidplay.libsidplay.mem.IKernal.KERNAL; import static de.quippy.sidplay.libsidplay.mem.IPSIDDrv.PSIDDRV; import static de.quippy.sidplay.libsidplay.mem.IPowerOn.POWERON; + import de.quippy.sidplay.libsidplay.common.C64Env; import de.quippy.sidplay.libsidplay.common.Event; import de.quippy.sidplay.libsidplay.common.EventScheduler; import de.quippy.sidplay.libsidplay.common.IEventContext; -import de.quippy.sidplay.libsidplay.common.SIDBuilder; -import de.quippy.sidplay.libsidplay.common.SIDEmu; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_clock_t; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_config_t; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_env_t; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_info_t; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_model_t; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_player_t; +import de.quippy.sidplay.libsidplay.common.SIDBuilder; +import de.quippy.sidplay.libsidplay.common.SIDEmu; import de.quippy.sidplay.libsidplay.common.mos6510.C64Environment; import de.quippy.sidplay.libsidplay.common.mos6510.MOS6510; import de.quippy.sidplay.libsidplay.common.mos6510.SID6510; diff --git a/source/de/quippy/sidplay/libsidplay/SIDPlay2.java b/source/de/quippy/sidplay/libsidplay/SIDPlay2.java index bc2b75c..261fa06 100644 --- a/source/de/quippy/sidplay/libsidplay/SIDPlay2.java +++ b/source/de/quippy/sidplay/libsidplay/SIDPlay2.java @@ -16,6 +16,7 @@ package de.quippy.sidplay.libsidplay; import static de.quippy.sidplay.libsidplay.Player.SID2_TIME_BASE; + import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_config_t; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_info_t; import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_player_t; diff --git a/source/de/quippy/sidplay/libsidplay/common/mos6510/MOS6510.java b/source/de/quippy/sidplay/libsidplay/common/mos6510/MOS6510.java index 6b02b37..a20b901 100644 --- a/source/de/quippy/sidplay/libsidplay/common/mos6510/MOS6510.java +++ b/source/de/quippy/sidplay/libsidplay/common/mos6510/MOS6510.java @@ -29,8 +29,8 @@ import java.util.logging.Logger; import de.quippy.sidplay.libsidplay.common.Event; -import de.quippy.sidplay.libsidplay.common.IEventContext; import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; +import de.quippy.sidplay.libsidplay.common.IEventContext; public class MOS6510 extends C64Environment /* extends Event */{ diff --git a/source/de/quippy/sidplay/libsidplay/components/mos6526/MOS6526.java b/source/de/quippy/sidplay/libsidplay/components/mos6526/MOS6526.java index 87db1ce..fab63aa 100644 --- a/source/de/quippy/sidplay/libsidplay/components/mos6526/MOS6526.java +++ b/source/de/quippy/sidplay/libsidplay/components/mos6526/MOS6526.java @@ -18,10 +18,11 @@ import static de.quippy.sidplay.libsidplay.Config.S_A_WHITE_EMAIL; import static de.quippy.sidplay.libsidplay.common.SIDEndian.endian_16hi8; import static de.quippy.sidplay.libsidplay.common.SIDEndian.endian_16lo8; + import de.quippy.sidplay.libsidplay.common.Event; +import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; import de.quippy.sidplay.libsidplay.common.IComponent; import de.quippy.sidplay.libsidplay.common.IEventContext; -import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; public abstract class MOS6526 implements IComponent { diff --git a/source/de/quippy/sidplay/libsidplay/components/mos6526/SID6526.java b/source/de/quippy/sidplay/libsidplay/components/mos6526/SID6526.java index ffedfd7..5f62a0c 100644 --- a/source/de/quippy/sidplay/libsidplay/components/mos6526/SID6526.java +++ b/source/de/quippy/sidplay/libsidplay/components/mos6526/SID6526.java @@ -18,11 +18,12 @@ import static de.quippy.sidplay.libsidplay.Config.S_A_WHITE_EMAIL; import static de.quippy.sidplay.libsidplay.common.SIDEndian.endian_16hi8; import static de.quippy.sidplay.libsidplay.common.SIDEndian.endian_16lo8; + import de.quippy.sidplay.libsidplay.common.C64Env; import de.quippy.sidplay.libsidplay.common.Event; +import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; import de.quippy.sidplay.libsidplay.common.IComponent; import de.quippy.sidplay.libsidplay.common.IEventContext; -import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; public class SID6526 implements IComponent { diff --git a/source/de/quippy/sidplay/libsidplay/components/mos656x/MOS656X.java b/source/de/quippy/sidplay/libsidplay/components/mos656x/MOS656X.java index 947dfa2..d8e6278 100644 --- a/source/de/quippy/sidplay/libsidplay/components/mos656x/MOS656X.java +++ b/source/de/quippy/sidplay/libsidplay/components/mos656x/MOS656X.java @@ -17,6 +17,7 @@ import static de.quippy.sidplay.libsidplay.Config.S_A_WHITE_EMAIL; import static de.quippy.sidplay.libsidplay.common.SIDEndian.endian_16lo8; + import de.quippy.sidplay.libsidplay.common.Event; import de.quippy.sidplay.libsidplay.common.IComponent; import de.quippy.sidplay.libsidplay.common.IEventContext; diff --git a/source/de/quippy/sidplay/libsidplay/components/sidtune/InfoFile.java b/source/de/quippy/sidplay/libsidplay/components/sidtune/InfoFile.java index 0d9777f..0318080 100644 --- a/source/de/quippy/sidplay/libsidplay/components/sidtune/InfoFile.java +++ b/source/de/quippy/sidplay/libsidplay/components/sidtune/InfoFile.java @@ -18,6 +18,7 @@ package de.quippy.sidplay.libsidplay.components.sidtune; import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_NOT_MINE; + import de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus; public class InfoFile { diff --git a/source/de/quippy/sidplay/libsidplay/components/sidtune/Mus.java b/source/de/quippy/sidplay/libsidplay/components/sidtune/Mus.java index 214b7d0..c6f62d4 100644 --- a/source/de/quippy/sidplay/libsidplay/components/sidtune/Mus.java +++ b/source/de/quippy/sidplay/libsidplay/components/sidtune/Mus.java @@ -25,6 +25,7 @@ import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_ERROR; import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_NOT_MINE; import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_OK; + import de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus; public class Mus { diff --git a/source/de/quippy/sidplay/libsidplay/components/sidtune/P00.java b/source/de/quippy/sidplay/libsidplay/components/sidtune/P00.java index d725829..3f48810 100644 --- a/source/de/quippy/sidplay/libsidplay/components/sidtune/P00.java +++ b/source/de/quippy/sidplay/libsidplay/components/sidtune/P00.java @@ -21,6 +21,7 @@ import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_ERROR; import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_NOT_MINE; import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_OK; + import de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus; public class P00 { diff --git a/source/de/quippy/sidplay/libsidplay/components/sidtune/Prg.java b/source/de/quippy/sidplay/libsidplay/components/sidtune/Prg.java index 21a9e0b..77e4571 100644 --- a/source/de/quippy/sidplay/libsidplay/components/sidtune/Prg.java +++ b/source/de/quippy/sidplay/libsidplay/components/sidtune/Prg.java @@ -21,6 +21,7 @@ import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_ERROR; import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_NOT_MINE; import static de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus.LOAD_OK; + import de.quippy.sidplay.libsidplay.components.sidtune.SidTune.LoadStatus; public class Prg { diff --git a/source/de/quippy/sidplay/libsidplay/components/xsid/XSID.java b/source/de/quippy/sidplay/libsidplay/components/xsid/XSID.java index 15570cc..11bc3be 100644 --- a/source/de/quippy/sidplay/libsidplay/components/xsid/XSID.java +++ b/source/de/quippy/sidplay/libsidplay/components/xsid/XSID.java @@ -22,9 +22,9 @@ import java.util.logging.Logger; import de.quippy.sidplay.libsidplay.common.Event; +import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; import de.quippy.sidplay.libsidplay.common.IEventContext; import de.quippy.sidplay.libsidplay.common.SIDEmu; -import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; /** diff --git a/source/de/quippy/sidplay/resid_builder/ReSID.java b/source/de/quippy/sidplay/resid_builder/ReSID.java index cae1090..5c40ca5 100644 --- a/source/de/quippy/sidplay/resid_builder/ReSID.java +++ b/source/de/quippy/sidplay/resid_builder/ReSID.java @@ -21,14 +21,14 @@ import java.util.logging.Logger; import de.quippy.sidplay.libsidplay.common.C64Env; +import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; import de.quippy.sidplay.libsidplay.common.IEventContext; +import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_model_t; import de.quippy.sidplay.libsidplay.common.SIDBuilder; import de.quippy.sidplay.libsidplay.common.SIDEmu; -import de.quippy.sidplay.libsidplay.common.Event.event_phase_t; -import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_model_t; -import de.quippy.sidplay.resid_builder.resid.SID; import de.quippy.sidplay.resid_builder.resid.ISIDDefs.chip_model; import de.quippy.sidplay.resid_builder.resid.ISIDDefs.sampling_method; +import de.quippy.sidplay.resid_builder.resid.SID; public class ReSID extends SIDEmu { diff --git a/source/de/quippy/sidplay/resid_builder/ReSIDBuilder.java b/source/de/quippy/sidplay/resid_builder/ReSIDBuilder.java index c5c0668..a69e63b 100644 --- a/source/de/quippy/sidplay/resid_builder/ReSIDBuilder.java +++ b/source/de/quippy/sidplay/resid_builder/ReSIDBuilder.java @@ -18,9 +18,9 @@ import java.util.ArrayList; import de.quippy.sidplay.libsidplay.common.C64Env; +import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_model_t; import de.quippy.sidplay.libsidplay.common.SIDBuilder; import de.quippy.sidplay.libsidplay.common.SIDEmu; -import de.quippy.sidplay.libsidplay.common.ISID2Types.sid2_model_t; /******************************************************************************* diff --git a/source/de/quippy/sidplay/resid_builder/resid/Filter.java b/source/de/quippy/sidplay/resid_builder/resid/Filter.java index 672d1a9..e7eb557 100644 --- a/source/de/quippy/sidplay/resid_builder/resid/Filter.java +++ b/source/de/quippy/sidplay/resid_builder/resid/Filter.java @@ -22,6 +22,7 @@ package de.quippy.sidplay.resid_builder.resid; import static de.quippy.sidplay.resid_builder.resid.SID.ANTTI_LANKILA_PATCH; + import de.quippy.sidplay.resid_builder.resid.ISIDDefs.chip_model; diff --git a/source/de/quippy/sidplay/resid_builder/resid/WaveformGenerator.java b/source/de/quippy/sidplay/resid_builder/resid/WaveformGenerator.java index 651b283..a0c19e3 100644 --- a/source/de/quippy/sidplay/resid_builder/resid/WaveformGenerator.java +++ b/source/de/quippy/sidplay/resid_builder/resid/WaveformGenerator.java @@ -22,6 +22,7 @@ package de.quippy.sidplay.resid_builder.resid; import static de.quippy.sidplay.resid_builder.resid.SID.ANTTI_LANKILA_PATCH; + import de.quippy.sidplay.resid_builder.resid.ISIDDefs.chip_model; /**