001: /*
002: * Copyright (c) 2007, Sun Microsystems, Inc.
003: *
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * * Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in
014: * the documentation and/or other materials provided with the
015: * distribution.
016: * * Neither the name of Sun Microsystems, Inc. nor the names of its
017: * contributors may be used to endorse or promote products derived
018: * from this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
023: * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
024: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032: package example.mmademo;
033:
034: import java.util.*;
035: import java.io.*;
036: import javax.microedition.midlet.*;
037: import javax.microedition.lcdui.*;
038: import javax.microedition.media.*;
039: import javax.microedition.media.control.*;
040:
041: /**
042: * Drummer Canvas
043: *
044: * @version 1.1
045: */
046: public class DrummerCanvas extends Canvas implements CommandListener {
047:
048: private static final String TITLE = "MMAPI Drummer";
049: private static final String LOGO = "/icons/logo.png";
050: private Command backCommand = new Command("Back", Command.BACK, 1);
051: private Command helpCommand = new Command("Quick Help",
052: Command.ITEM, 10);
053:
054: private static int TITLE_TOP = 2;
055: private static int LOGO_GAP = 2;
056: private static int CURR_DRUM_GAP = 2;
057: private static int STATUS_GAP = 2;
058:
059: private Image logo = null;
060: private Utils.BreadCrumbTrail parent;
061: private SimpleTones tones;
062:
063: private String status = "";
064: private String currDrum = "";
065:
066: private int displayWidth = -1;
067: private int displayHeight = -1;
068: private int textHeight = 10;
069: private int logoTop = 0;
070: private int currDrumTop = 0;
071: private int statusTop = 0;
072:
073: private MIDIControl mc;
074:
075: // the MIDI numbers for the drums
076: private static final int[] DRUM_NUMBERS = { 0, // not used
077: 0x2A, // 1: closed hihat
078: 0x2E, // 2: open hihat
079: 0x36, // 3: Tambourine
080: 0x32, // 4: hi tom
081: 0x2F, // 5: mid tom
082: 0x2B, // 6: low tom
083: 0x33, // 7: ride cymbal
084: 0x38, // 8: cow bell
085: 0x31, // 9: crash cymbal
086: 0x24, // *: bass drum
087: 0x27, // 0: hand clap
088: 0x28, // #: snare drum
089: };
090:
091: private static final String[] DRUM_NAMES = { "", // not used
092: "Closed Hi-Hat", // 1
093: "Open Hi-Hat", // 2
094: "Tambourine", // 3
095: "Hi Tom", // 4
096: "Mid Tom", // 5
097: "Low Tom", // 6
098: "Ride Cymbal", // 7
099: "Cow Bell", // 8
100: "Crash Cymbal", // 9
101: "Bass Drum", // *
102: "Hand Clap", // 0
103: "Snare Drum", // #
104: };
105:
106: private static final String[] SHORT_DRUM_NAMES = { "", "CH", "OH",
107: "TB", "HT", "MT", "LT", "RC", "CB", "CC", "BD", "HC", "SD", };
108:
109: private static final int[] DRUM_KEYS = {
110: 0, // not used
111: KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, KEY_NUM6,
112: KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_STAR, KEY_NUM0,
113: KEY_POUND, };
114:
115: private static void debugOut(String s) {
116: Utils.debugOut("DrummerCanvas: " + s);
117: }
118:
119: public DrummerCanvas(SimpleTones tones, Utils.BreadCrumbTrail parent) {
120: super ();
121: this .parent = parent;
122: this .tones = tones;
123: }
124:
125: // //////////////////////////// interface Utils.BreadCrumbTrail ///////////
126:
127: public Displayable go(Displayable d) {
128: return parent.go(d);
129: }
130:
131: public Displayable goBack() {
132: return parent.goBack();
133: }
134:
135: public Displayable replaceCurrent(Displayable d) {
136: return parent.replaceCurrent(d);
137: }
138:
139: public Displayable getCurrentDisplayable() {
140: return parent.getCurrentDisplayable();
141: }
142:
143: // ///////////////////////// interface CommandListener ////////////////////
144:
145: public void commandAction(Command c, Displayable s) {
146: if (c == backCommand) {
147: goBack();
148: } else if (c == helpCommand) {
149: showHelp();
150: } else if (s != this ) {
151: // e.g. when list item in MetaData display list is pressed
152: goBack();
153: }
154: }
155:
156: private void status(String s) {
157: status = s;
158: repaint(0, statusTop, displayWidth, textHeight);
159: serviceRepaints();
160: }
161:
162: private void setCurrDrum(int num) {
163: currDrum = DRUM_NAMES[num];
164: repaint(0, currDrumTop, displayWidth, textHeight);
165: serviceRepaints();
166: }
167:
168: public void updateDisplay() {
169: repaint();
170: serviceRepaints();
171: }
172:
173: public void show() {
174: addCommand(backCommand);
175: addCommand(helpCommand);
176: setCommandListener(this );
177: status("Prefetching and getting MIDIControl");
178: updateDisplay();
179: new Thread(new Runnable() {
180: public void run() {
181: try {
182: mc = tones.getMIDIControl();
183: status("Ready.");
184: } catch (Exception e) {
185: status(Utils.friendlyException(e));
186: mc = null;
187: }
188: }
189: }).start();
190: }
191:
192: // ///////////////////////// Canvas callbacks ///////////////////////////////
193:
194: protected void keyPressed(int keycode) {
195: try {
196: for (int num = 1; num < DRUM_KEYS.length; num++) {
197: if (keycode == DRUM_KEYS[num]) {
198: playDrum(num);
199: return;
200: }
201: }
202: // action code currently not used
203: /*
204: int code = getGameAction(keycode);
205: if (code == RIGHT) {
206: } else if (code == LEFT) {
207: } else if (code == UP) {
208: } else if (code == DOWN) {
209: } else if (code == FIRE) {
210: }
211: */
212: } catch (Throwable t) {
213: Utils.error(t, parent);
214: }
215: }
216:
217: private void playDrum(int num) {
218: if (mc == null)
219: return;
220: setCurrDrum(num);
221: mc.shortMidiEvent(0x99, DRUM_NUMBERS[num], 120);
222: mc.shortMidiEvent(0x99, DRUM_NUMBERS[num], 0);
223: }
224:
225: private boolean intersects(int clipY, int clipHeight, int y, int h) {
226: return (clipY <= y + h && clipY + clipHeight >= y);
227: }
228:
229: public void paint(Graphics g) {
230: try {
231: if (displayHeight == -1) {
232: displayWidth = getWidth();
233: displayHeight = getHeight();
234: textHeight = g.getFont().getHeight();
235: logo = getLogo();
236:
237: int currTop = TITLE_TOP + textHeight;
238: if (logo != null) {
239: currTop += LOGO_GAP;
240: logoTop = currTop;
241: currTop += logo.getHeight();
242: }
243:
244: // curr drum: before-last line
245: currDrumTop = displayHeight - 2 * textHeight
246: - STATUS_GAP;
247: // status: last line.
248: statusTop = displayHeight - textHeight;
249: }
250:
251: int clipX = g.getClipX();
252: int clipY = g.getClipY();
253: int clipWidth = g.getClipWidth();
254: int clipHeight = g.getClipHeight();
255: // background
256: g.setColor(0);
257: g.fillRect(clipX, clipY, clipWidth, clipHeight);
258: // title
259: if (intersects(clipY, clipHeight, TITLE_TOP, textHeight)) {
260: g.setColor(0xFF7f00);
261: g.drawString(TITLE, displayWidth >> 1, TITLE_TOP,
262: Graphics.TOP | Graphics.HCENTER);
263: }
264: // logo
265: if (logo != null
266: && intersects(clipY, clipHeight, logoTop, logo
267: .getHeight())) {
268: g.drawImage(logo, displayWidth / 2, logoTop,
269: Graphics.TOP | Graphics.HCENTER);
270: }
271:
272: // Curr Drum
273: if (intersects(clipY, clipHeight, currDrumTop, textHeight)) {
274: g.setColor(0xE0E0FF);
275: g.drawString(currDrum, 0, currDrumTop, Graphics.TOP
276: | Graphics.LEFT);
277: }
278: // Status
279: if (intersects(clipY, clipHeight, displayHeight
280: - textHeight, textHeight)) {
281: g.setColor(0xFAFAFA);
282: g.drawString(status, 0, displayHeight, Graphics.BOTTOM
283: | Graphics.LEFT);
284: }
285:
286: } catch (Throwable t) {
287: debugOut("in paint(): " + Utils.friendlyException(t));
288: }
289: }
290:
291: /**
292: * Show a page which explains the keys.
293: * For simplicity, the page is implemented as a list...
294: */
295: public void showHelp() {
296: Form form = new Form("Drummer Help");
297: StringItem stringItem = new StringItem("",
298: "Use the numeric keys to play drums. "
299: + "Each Key corresponds to a different drum.");
300: form.append(stringItem);
301: form.addCommand(backCommand);
302: form.setCommandListener(this );
303: go(form);
304: }
305:
306: private Image getLogo() {
307: if (logo == null) {
308: try {
309: logo = Image.createImage(LOGO);
310: } catch (Exception ex) {
311: logo = null;
312: }
313: if (logo == null) {
314: debugOut("can not load " + LOGO);
315: }
316: }
317: return logo;
318: }
319:
320: }
|