View Javadoc

1   package de.jos.game.aspect;
2   
3   import java.awt.Graphics2D;
4   import java.awt.Toolkit;
5   import java.awt.event.KeyEvent;
6   import java.util.ArrayList;
7   import java.util.List;
8   
9   import org.apache.commons.lang.StringUtils;
10  import org.aspectj.lang.annotation.After;
11  import org.aspectj.lang.annotation.Aspect;
12  import org.aspectj.lang.annotation.Pointcut;
13  
14  import com.golden.gamedev.object.GameFont;
15  import com.golden.gamedev.object.Timer;
16  
17  import de.jos.game.aspect.plugins.CanisterPlugin;
18  import de.jos.game.aspect.plugins.DebugPlugin;
19  import de.jos.game.aspect.plugins.LevelPlugin;
20  import de.jos.game.aspect.plugins.ScorePlugin;
21  import de.jos.game.objects.screen.AbstractGameObject;
22  
23  /***
24   * 
25   * @author Andreas Wuest
26   * 
27   */
28  
29  @Aspect
30  public class DebugConsole {
31  
32    static final String PROMPT = ">";
33    static final int PROMPT_LENGTH = PROMPT.length();
34  
35    private int currentLine = 0; // current line of console
36    private int currentCol = PROMPT_LENGTH; // current column of console
37  
38    private static final int MAX_LINES = 19; // maximum lines in console
39    private static final int MAX_COLS = 40; // maximum column before new line
40  
41    private List<String> newLines = new ArrayList<String>();
42  
43    private List<DebugPlugin> debugPlugins = new ArrayList<DebugPlugin>();
44  
45    private boolean showConsole = false;
46    private boolean blink = false;
47    private Timer blinkTimer = new Timer(200); // timer for blinking cursor
48  
49    public DebugConsole() {
50      newLines.add(PROMPT);
51      currentLine = 0;
52      showConsole = false;
53  
54      debugPlugins.add(new CanisterPlugin());
55      debugPlugins.add(new ScorePlugin());
56      debugPlugins.add(new LevelPlugin());
57    }
58  
59    @Pointcut("execution(@DebugConsoleAware public void de.jos.game.objects.screen.AbstractGameObject+.update(long)) && args(elapsedTime) && this(gameObject)")
60    public void callUpdate(AbstractGameObject gameObject, long elapsedTime) {}
61  
62    @Pointcut("execution(@DebugConsoleAware public void de.jos.game.objects.screen.AbstractGameObject+.render(Graphics2D)) && args(graphics) && this(gameObject)")
63    public void callRender(AbstractGameObject gameObject, Graphics2D graphics) {}
64  
65    @After("callUpdate(gameObject ,elapsedTime)")
66    public void update(AbstractGameObject gameObject, long elapsedTime) {
67      int keyCode = gameObject.bsInput.getKeyPressed(); // get key pressed
68  
69      if (keyCode == KeyEvent.VK_ESCAPE) {
70        showConsole = !showConsole;
71      }
72  
73      if (showConsole == false) {
74        return;
75      }
76  
77      if (blinkTimer.action(elapsedTime)) {
78        // if visible make invisible and vise versa
79        blink = !blink;
80      }
81  
82      // shift key down
83      boolean upperCase = gameObject.bsInput.isKeyDown(KeyEvent.VK_SHIFT);
84  
85      // caps lock on
86      boolean capsLock = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
87  
88      String st = ""; // holds character to add to console
89  
90      String line = null;
91      switch(keyCode) {
92  
93        case KeyEvent.VK_ENTER:
94  
95          line = newLines.get(currentLine);
96  
97          if (line.startsWith(PROMPT + "HELP")) {
98            addLine("help - this help");
99            addLine("clear - clears the console");
100 
101           for (DebugPlugin plugin : debugPlugins) {
102             addLine(plugin.getPluginName());
103           }
104 
105         } else if (line.startsWith(PROMPT + "CLEAR")) {
106           clearConsole();
107         } else {
108           // check the debug plugins
109 
110           // get the command by removing the prompt from the line
111           String cmd = line.substring(PROMPT.length()).trim();
112 
113           System.out.println(cmd);
114 
115           for (DebugPlugin plugin : debugPlugins) {
116             if (plugin.getPluginHelpCommand().equals(cmd)) {
117               addLine(plugin.getPluginHelp());
118             } else if (plugin.possibleCommandMatch(cmd)) {
119               plugin.executeCommand(gameObject, cmd);
120             }
121           }
122         }
123 
124         // add simple prompt
125         addLine(PROMPT);
126         currentCol = PROMPT.length();
127 
128         break;
129       case KeyEvent.VK_BACK_SPACE:
130         line = newLines.remove(currentLine);
131 
132         // two lines commands are not supported !!!
133         if (line.startsWith(PROMPT)) {
134           // process the code
135           if (line.length() > PROMPT_LENGTH) {
136             // delete last character
137             line = line.substring(0, line.length() - 1);
138 
139             // move column back one
140             currentCol--;
141           }
142         }
143 
144         newLines.add(currentLine, line);
145         break;
146       case KeyEvent.VK_BACK_QUOTE:
147         st = (upperCase) ? "~" : "`";
148         break;
149       case KeyEvent.VK_1:
150         st = (upperCase) ? "!" : "1";
151         break;
152       case KeyEvent.VK_2:
153         st = (upperCase) ? "@" : "2";
154         break;
155       case KeyEvent.VK_3:
156         st = (upperCase) ? "#" : "3";
157         break;
158       case KeyEvent.VK_4:
159         st = (upperCase) ? "$" : "4";
160         break;
161       case KeyEvent.VK_5:
162         st = (upperCase) ? "%" : "5";
163         break;
164       case KeyEvent.VK_6:
165         st = (upperCase) ? "^" : "6";
166         break;
167       case KeyEvent.VK_7:
168         st = (upperCase) ? "&" : "7";
169         break;
170       case KeyEvent.VK_8:
171         st = (upperCase) ? "*" : "8";
172         break;
173       case KeyEvent.VK_9:
174         st = (upperCase) ? "(" : "9";
175         break;
176       case KeyEvent.VK_0:
177         st = (upperCase) ? ")" : "0";
178         break;
179       case KeyEvent.VK_MINUS:
180         st = (upperCase) ? "_" : "-";
181         break;
182       case KeyEvent.VK_EQUALS:
183         st = (upperCase) ? "+" : "=";
184         break;
185       case KeyEvent.VK_BACK_SLASH:
186         st = (upperCase) ? "|" : "//";
187         break;
188       case KeyEvent.VK_OPEN_BRACKET:
189         st = (upperCase) ? "{" : "[";
190         break;
191       case KeyEvent.VK_CLOSE_BRACKET:
192         st = (upperCase) ? "}" : "]";
193         break;
194       case KeyEvent.VK_SEMICOLON:
195         st = (upperCase) ? ":" : ";";
196         break;
197       case KeyEvent.VK_QUOTE:
198         st = (upperCase) ? "\"" : "'";
199         break;
200       case KeyEvent.VK_COMMA:
201         st = (upperCase) ? "<" : ",";
202         break;
203       case KeyEvent.VK_PERIOD:
204         st = (upperCase) ? ">" : ".";
205         break;
206       case KeyEvent.VK_SLASH:
207         st = (upperCase) ? "?" : "/";
208         break;
209       case KeyEvent.VK_DIVIDE:
210         st = "/";
211         break;
212       case KeyEvent.VK_MULTIPLY:
213         st = "*";
214         break;
215       case KeyEvent.VK_SUBTRACT:
216         st = "-";
217         break;
218       case KeyEvent.VK_ADD:
219         st = "+";
220         break;
221       case KeyEvent.VK_DECIMAL:
222         st = ".";
223         break;
224       case KeyEvent.VK_SPACE:
225         st = " ";
226         break;
227       default:
228         st = StringUtils.lowerCase(KeyEvent.getKeyText(keyCode));
229         if (st.startsWith("numpad")) {
230           // convert numpadX -> X
231           st = st.substring(7);
232         }
233 
234         if (st.length() == 0 || st.length() > 1) {
235           // invalid key
236           return;
237         }
238         if (keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z) {
239           // always to uppercase for bit map font.
240           st = StringUtils.upperCase(st);
241         }
242         break;
243     }
244 
245     String str = newLines.remove(currentLine) + st;
246     if (str.length() > MAX_COLS) {
247       str = str.substring(0, MAX_COLS);
248       currentCol = MAX_COLS - 1;
249     }
250     newLines.add(currentLine, str);
251 
252     currentCol++;
253   }
254 
255   @After("callRender(gameObject ,graphics)")
256   public void render(AbstractGameObject gameObject, Graphics2D graphics) {
257     if (showConsole == false) {
258       return;
259     }
260 
261     GameFont font = gameObject.getResourceContainer().getGameFont();
262 
263     int index = 0;
264     for (String line : newLines) {
265 
266       if (index == currentLine && !blink) {
267         // draw cursor
268         font.drawString(graphics, line + "_", 20, 40 + (index * 20));
269       } else {
270         // just draw the line
271         font.drawString(graphics, line, 20, 40 + (index * 20));
272       }
273       index++;
274     }
275   }
276 
277   private void addLine(List<String> newLines) {
278     for (String line : newLines) {
279       addLine(line);
280     }
281   }
282 
283   private void addLine(String lineToAdd) {
284     newLines.add(StringUtils.upperCase(lineToAdd));
285     currentLine++;
286     shiftLinesUp();
287   }
288 
289   private void shiftLinesUp() {
290     while (newLines.size() > (MAX_LINES + 1)) {
291       newLines.remove(0);
292     }
293     if (newLines.size() == (MAX_LINES + 1)) {
294       currentLine = MAX_LINES;
295     }
296   }
297 
298   private void clearConsole() {
299     newLines.clear();
300     currentLine = -1;
301   }
302 
303 }