# HG changeset patch # User Matti Hamalainen # Date 1296496001 -7200 # Node ID df494a65bf8c1eff9c1bc56a5c6103a60df2a080 # Parent 932582867c11da5ddc03e5fe55203f62ae4de33a More work. diff -r 932582867c11 -r df494a65bf8c Makefile --- a/Makefile Mon Jan 31 16:09:28 2011 +0200 +++ b/Makefile Mon Jan 31 19:46:41 2011 +0200 @@ -1,7 +1,7 @@ # Settings, directories RUN=Ristipolku.class -RESOURCES=graphics/board.png +RESOURCES=graphics/board.png sounds/*.wav CLASSES=game/Piece.java game/PieceType.java game/Engine.java game/Interpolate.java game/ResourceLoader.java diff -r 932582867c11 -r df494a65bf8c game/Engine.java --- a/game/Engine.java Mon Jan 31 16:09:28 2011 +0200 +++ b/game/Engine.java Mon Jan 31 19:46:41 2011 +0200 @@ -18,83 +18,209 @@ import javax.sound.sampled.*; -enum Sound { - PIECE_PLACED("placed.wav"), - MUSIC_GAME("gamemusic.wav"); +enum Sound +{ + PIECE_PLACED("placed.wav", true), + + MUSIC_GAME1("gamemusic.wav", false); - final String name; - private Clip clip; - Sound(String name) + private final String name; + private final boolean effect; + + Sound(String name, boolean effect) { this.name = name; + this.effect = effect; } - - public boolean initialized() + + public String getName() { - return clip != null; + return this.name; } - public static void load(String path) throws IOException + public boolean isEffect() + { + return effect; + } +} + + +class SoundElement implements Runnable +{ + private final String name; + private Clip clip; + private AudioInputStream stream; + private AudioFormat format; + private SourceDataLine line; + private Thread playThread; + private int loopCount; + private boolean doPlay; + + SoundElement(String filename, boolean effect) throws IOException { - for (Sound snd : Sound.values()) { - String filename = path + snd.name; - ResourceLoader res = new ResourceLoader(filename); - if (res == null || res.getStream() == null) - { - throw new IOException("Could not load audio resource '"+filename+"'.\n"); + this.name = filename; + + ResourceLoader res = new ResourceLoader(name); + if (res == null || res.getStream() == null) + { + throw new IOException("Could not load audio resource '"+name+"'.\n"); + } + + try { + stream = AudioSystem.getAudioInputStream(res.getStream()); + } + catch (UnsupportedAudioFileException e) { + throw new IOException("Unsupported audio file format for '"+name+"'.\n"); + } + catch (IOException e) + { + throw new IOException("Could not load audio resource '"+name+"'.\n"); + } + + format = stream.getFormat(); + + if (effect) { + System.out.print("Loading '"+name+"' as a clip\n"); + try { + clip = AudioSystem.getClip(); + clip.open(stream); } + catch (LineUnavailableException e) + { + throw new IOException("Line unavailable for '"+name+"'.\n"); + } + finally { + stream.close(); + } + } + else + { + clip = null; + System.out.print("Loading '"+name+"' as stream\n"); + try { - AudioInputStream is = AudioSystem.getAudioInputStream(res.getStream()); + SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format); + System.out.print("info: "+stream.getFrameLength() + ", " + format.getFrameSize() + "\n"); + line = (SourceDataLine) AudioSystem.getLine(info); + line.open(format); + } + catch (LineUnavailableException e) { + throw new IOException("Line unavailable for '"+name+"'.\n"); } - catch (UnsupportedAudioFileException e) { - throw new IOException("Unsupported audio file format for '"+filename+"'.\n"); - } - catch (IOException e) + } + } + + public boolean isClip() + { + return (clip != null && line == null); + } + + public void play() + { + System.out.print("Sound("+name+").play()\n"); + if (isClip()) + { + clip.setFramePosition(0); + clip.start(); + } + else + { + if (playThread == null) { - throw new IOException("Could not load audio resource '"+filename+"'.\n"); + doPlay = true; + loopCount = 1; + playThread = new Thread(this); + playThread.start(); } } } - public void play() - { - if (clip == null) - return; - - clip.setFramePosition(0); - clip.start(); - } - public void loop(int n) { - if (clip == null) - return; - - if (n < 0) - clip.loop(Clip.LOOP_CONTINUOUSLY); + System.out.print("Sound("+name+").loop("+n+")\n"); + if (isClip()) + { + clip.setFramePosition(0); + if (n < 0) + clip.loop(Clip.LOOP_CONTINUOUSLY); + else + clip.loop(n); + } else - clip.loop(n); + { + if (playThread == null) + { + doPlay = true; + loopCount = n; + playThread = new Thread(this); + playThread.start(); + } + } } public void stop() { - if (clip == null) - return; - - if (clip.isRunning()) - clip.stop(); + if (isClip()) + { + if (clip.isRunning()) + clip.stop(); + } + else + { + if (playThread != null) + { + playThread.interrupt(); + doPlay = false; + playThread = null; + } + } } public boolean isPlaying() { - if (clip == null) - return false; + if (isClip()) + return clip.isRunning(); + else + return (playThread != null && doPlay); + } + + public void run() + { + line.start(); + byte[] buf = new byte[line.getBufferSize()]; - return clip.isRunning(); + while (doPlay && (loopCount > 0 || loopCount == -1)) + { + try { + int numRead = 0; + while ((numRead = stream.read(buf, 0, buf.length)) >= 0 && doPlay) + { + int offset = 0; + while (offset < numRead) + { + System.out.print("audioThread: offs="+offset+", numread="+numRead+"\n"); + offset += line.write(buf, offset, numRead - offset); + } + } + line.drain(); + + System.out.print("audioThread: stream.reset()\n"); + stream.reset(); + } + catch (IOException e) { + } + + if (loopCount > 0) + loopCount--; + } + + line.stop(); + doPlay = false; } } + class PathInfo { public int in, inX, inY, out, outX, outY; @@ -279,7 +405,12 @@ BufferedImage lautaBG = null, lautaBGScaled = null; Dimension oldDim; float clock; - Sound sounds; + SoundElement[] sounds; + + public SoundElement snd(Sound snd) + { + return sounds[snd.ordinal()]; + } public Engine() { @@ -292,17 +423,23 @@ { ResourceLoader res = new ResourceLoader("graphics/board.png"); lautaBG = ImageIO.read(res.getStream()); - sounds.load("sounds/"); + + sounds = new SoundElement[16]; + for (Sound s : Sound.values()) + { + System.out.print(s +" = "+ s.ordinal() +"\n"); + sounds[s.ordinal()] = new SoundElement("sounds/" + s.getName(), s.isEffect()); + } } catch (IOException e) { /* JOptionPane.showMessageDialog(null, - "Could not load some of the resources.", + e.getMessage(), "Initialization error", JOptionPane.ERROR_MESSAGE); */ - System.out.print("Could not load some of the resources.\n"); + System.out.print(e.getMessage()); } lauta = new GameBoard(); @@ -316,7 +453,8 @@ requestFocus(); } - sounds.MUSIC_GAME.loop(-1); + snd(Sound.MUSIC_GAME1).loop(-1); +// snd(Sound.PIECE_PLACED).loop(-1); } public void startThreads() @@ -395,7 +533,7 @@ public void keyPressed(KeyEvent e) { - System.out.print("lol\n"); + System.out.print("running "+ snd(Sound.MUSIC_GAME1) + "\n"); switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: @@ -410,6 +548,8 @@ case KeyEvent.VK_ENTER: lauta.pieceFinishTurn(); + snd(Sound.PIECE_PLACED).stop(); + snd(Sound.PIECE_PLACED).play(); break; } } diff -r 932582867c11 -r df494a65bf8c game/Piece.java --- a/game/Piece.java Mon Jan 31 16:09:28 2011 +0200 +++ b/game/Piece.java Mon Jan 31 19:46:41 2011 +0200 @@ -168,8 +168,7 @@ g.rotate(currAngle, x + dim / 2.0f, y + dim / 2.0f); // g.transform(tf); - if (type == PieceType.ACTIVE) - System.out.print("angle = " + currAngle + "\n"); +// if (type == PieceType.ACTIVE) System.out.print("angle = " + currAngle + "\n"); switch (type) { case LOCKED: g.setPaint(Color.green); break;