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;
36 private int currentCol = PROMPT_LENGTH;
37
38 private static final int MAX_LINES = 19;
39 private static final int MAX_COLS = 40;
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);
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();
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
79 blink = !blink;
80 }
81
82
83 boolean upperCase = gameObject.bsInput.isKeyDown(KeyEvent.VK_SHIFT);
84
85
86 boolean capsLock = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
87
88 String st = "";
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
109
110
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
125 addLine(PROMPT);
126 currentCol = PROMPT.length();
127
128 break;
129 case KeyEvent.VK_BACK_SPACE:
130 line = newLines.remove(currentLine);
131
132
133 if (line.startsWith(PROMPT)) {
134
135 if (line.length() > PROMPT_LENGTH) {
136
137 line = line.substring(0, line.length() - 1);
138
139
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
231 st = st.substring(7);
232 }
233
234 if (st.length() == 0 || st.length() > 1) {
235
236 return;
237 }
238 if (keyCode >= KeyEvent.VK_A && keyCode <= KeyEvent.VK_Z) {
239
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
268 font.drawString(graphics, line + "_", 20, 40 + (index * 20));
269 } else {
270
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 }