summary refs log tree commit diff stats
path: root/src/com/fourisland
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/fourisland')
-rw-r--r--src/com/fourisland/fourpuzzle/util/PauseTimer.java12
-rwxr-xr-xsrc/com/fourisland/fourpuzzle/window/ChoiceWindow.java2
-rw-r--r--src/com/fourisland/fourpuzzle/window/MessageEscape.java79
-rw-r--r--src/com/fourisland/fourpuzzle/window/MessageWindow.java115
-rwxr-xr-xsrc/com/fourisland/fourpuzzle/window/SystemGraphic.java9
-rw-r--r--src/com/fourisland/fourpuzzle/window/TextRenderer.java306
6 files changed, 420 insertions, 103 deletions
diff --git a/src/com/fourisland/fourpuzzle/util/PauseTimer.java b/src/com/fourisland/fourpuzzle/util/PauseTimer.java index 7d66d1a..f26f105 100644 --- a/src/com/fourisland/fourpuzzle/util/PauseTimer.java +++ b/src/com/fourisland/fourpuzzle/util/PauseTimer.java
@@ -29,12 +29,12 @@ public class PauseTimer {
29 29
30 if (in.isElapsed()) 30 if (in.isElapsed())
31 { 31 {
32 if (ticks == 0) 32 ticks--;
33 { 33 }
34 return true; 34
35 } else { 35 if (ticks <= 0)
36 ticks--; 36 {
37 } 37 return true;
38 } 38 }
39 39
40 return false; 40 return false;
diff --git a/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java b/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java index 4926a6d..90f2d96 100755 --- a/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java +++ b/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java
@@ -79,7 +79,7 @@ public class ChoiceWindow implements Renderable {
79 g2.drawImage(Window.Selector.getImage(fw-Window.Selector.getLeftX(), fh-Window.Selector.getTopY()), tx-SPACER, ty-fh-SPACER, null); 79 g2.drawImage(Window.Selector.getImage(fw-Window.Selector.getLeftX(), fh-Window.Selector.getTopY()), tx-SPACER, ty-fh-SPACER, null);
80 } 80 }
81 81
82 g2.setPaint(new TexturePaint(SystemGraphic.getTextColor(), new Rectangle(tx, ty, fw, fh))); 82 g2.setPaint(new TexturePaint(SystemGraphic.getTextColor(0), new Rectangle(tx, ty, fw, fh)));
83 g2.drawString(choice, tx, ty); 83 g2.drawString(choice, tx, ty);
84 84
85 ty+=(SPACER+fh); 85 ty+=(SPACER+fh);
diff --git a/src/com/fourisland/fourpuzzle/window/MessageEscape.java b/src/com/fourisland/fourpuzzle/window/MessageEscape.java new file mode 100644 index 0000000..2ae55b2 --- /dev/null +++ b/src/com/fourisland/fourpuzzle/window/MessageEscape.java
@@ -0,0 +1,79 @@
1/*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5
6package com.fourisland.fourpuzzle.window;
7
8import java.util.regex.MatchResult;
9import java.util.regex.Matcher;
10import java.util.regex.Pattern;
11
12
13/**
14 *
15 * @author hatkirby
16 */
17public enum MessageEscape
18{
19 Color("\\\\C\\[(\\d+)\\]"),
20 Pause("\\\\P");
21
22 private Pattern pattern;
23 private MessageEscape(String pattern)
24 {
25 this.pattern = Pattern.compile(pattern);
26 }
27
28 public static String removeEscapes(String message)
29 {
30 for (MessageEscape escape : values())
31 {
32 message = escape.pattern.matcher(message).replaceAll("");
33 }
34
35 return message;
36 }
37
38 public boolean match(String substring)
39 {
40 Matcher m = pattern.matcher(substring);
41
42 return (m.lookingAt() && (m.start() == 0));
43 }
44
45 public String removeEscape(String message)
46 {
47 return pattern.matcher(message).replaceFirst("");
48 }
49
50 MessageEscapePair getMatch(String substring)
51 {
52 Matcher m = pattern.matcher(substring);
53 m.lookingAt();
54
55 return new MessageEscapePair(this, m.toMatchResult());
56 }
57}
58
59class MessageEscapePair
60{
61 MessageEscape escape;
62 MatchResult match;
63
64 public MessageEscapePair(MessageEscape escape, MatchResult match)
65 {
66 this.escape = escape;
67 this.match = match;
68 }
69
70 public MessageEscape getMessageEscape()
71 {
72 return escape;
73 }
74
75 public MatchResult getMatchResult()
76 {
77 return match;
78 }
79} \ No newline at end of file
diff --git a/src/com/fourisland/fourpuzzle/window/MessageWindow.java b/src/com/fourisland/fourpuzzle/window/MessageWindow.java index dab67d1..709704a 100644 --- a/src/com/fourisland/fourpuzzle/window/MessageWindow.java +++ b/src/com/fourisland/fourpuzzle/window/MessageWindow.java
@@ -14,11 +14,7 @@ import com.fourisland.fourpuzzle.util.Inputable;
14import com.fourisland.fourpuzzle.util.Interval; 14import com.fourisland.fourpuzzle.util.Interval;
15import com.fourisland.fourpuzzle.util.Renderable; 15import com.fourisland.fourpuzzle.util.Renderable;
16import java.awt.Graphics2D; 16import java.awt.Graphics2D;
17import java.awt.Rectangle;
18import java.awt.TexturePaint;
19import java.awt.image.BufferedImage; 17import java.awt.image.BufferedImage;
20import java.util.ArrayList;
21import java.util.List;
22import java.util.concurrent.CountDownLatch; 18import java.util.concurrent.CountDownLatch;
23 19
24/** 20/**
@@ -30,10 +26,9 @@ public class MessageWindow implements Renderable {
30 private static final int SPACER = 4; 26 private static final int SPACER = 4;
31 private static final int HEIGHT = (4*(Display.getFontMetrics().getHeight()+SPACER)); 27 private static final int HEIGHT = (4*(Display.getFontMetrics().getHeight()+SPACER));
32 28
33 private volatile List<String> messages; 29 TextRenderer tr;
34 int width; 30 int width;
35 BufferedImage cacheBase; 31 BufferedImage cacheBase;
36 int num = 0;
37 int upTo = 0; 32 int upTo = 0;
38 boolean bounceArrow = false; 33 boolean bounceArrow = false;
39 Interval in = Interval.createTickInterval(4); 34 Interval in = Interval.createTickInterval(4);
@@ -42,7 +37,9 @@ public class MessageWindow implements Renderable {
42 width = Game.WIDTH - Window.Default.getFullWidth(0); 37 width = Game.WIDTH - Window.Default.getFullWidth(0);
43 cacheBase = Window.Default.getImage(width, HEIGHT); 38 cacheBase = Window.Default.getImage(width, HEIGHT);
44 39
45 initalizeMessages(message); 40 tr = new TextRenderer(width);
41 tr.setEscapes(true);
42 tr.initalizeText(message);
46 } 43 }
47 44
48 boolean hasFace = false; 45 boolean hasFace = false;
@@ -55,7 +52,10 @@ public class MessageWindow implements Renderable {
55 this.face = FaceSet.getFaceSet(faceSet).getImage(face); 52 this.face = FaceSet.getFaceSet(faceSet).getImage(face);
56 hasFace = true; 53 hasFace = true;
57 54
58 initalizeMessages(message); 55 tr = new TextRenderer(width);
56 tr.setEscapes(true);
57 tr.setIndent(48 + (SPACER*2));
58 tr.initalizeText(message);
59 } 59 }
60 60
61 private static void displayMessage(final MessageWindow mw) throws InterruptedException 61 private static void displayMessage(final MessageWindow mw) throws InterruptedException
@@ -101,96 +101,24 @@ public class MessageWindow implements Renderable {
101 displayMessage(new MessageWindow(message, faceSet, face)); 101 displayMessage(new MessageWindow(message, faceSet, face));
102 } 102 }
103 103
104 private void initalizeMessages(String message)
105 {
106 messages = new ArrayList<String>();
107
108 int length = width - SPACER;
109 if (hasFace)
110 {
111 length -= (48 + (SPACER*3));
112 }
113
114 String temp = message;
115 int len = 0;
116 while (!temp.isEmpty())
117 {
118 while ((Display.getFontMetrics().stringWidth(temp.substring(0, len)) < length) && (len < temp.length()))
119 {
120 len++;
121 }
122
123 if (len != temp.length())
124 {
125 while ((!temp.substring(len, len+1).equals(" ")) && (len > 0))
126 {
127 len--;
128 }
129 }
130
131 messages.add(temp.substring(0, len));
132
133 if (len != temp.length())
134 {
135 temp = temp.substring(len+1);
136 } else {
137 temp = "";
138 }
139
140 len = 0;
141 }
142
143 setLength();
144 }
145
146 private void setLength()
147 {
148 num = 0;
149
150 for (int i=0;i<Math.min(messages.size(),4);i++)
151 {
152 num += messages.get(i).length();
153 }
154 }
155
156 public void render(Graphics2D g2) 104 public void render(Graphics2D g2)
157 { 105 {
158 int y = MessageWindowLocation.Bottom.getY(); 106 int y = MessageWindowLocation.Bottom.getY();
159
160 Display.setFont(g2);
161 107
162 g2.drawImage(cacheBase, 0, y, null); 108 g2.drawImage(cacheBase, 0, y, null);
163 109
164 int fh = g2.getFontMetrics().getHeight(); 110 int fh = g2.getFontMetrics().getHeight();
165 int tx = Window.Default.getLeftX();
166 int ty = Window.Default.getTopY()+fh-(SPACER/2)+y; 111 int ty = Window.Default.getTopY()+fh-(SPACER/2)+y;
167 int msgs = Math.min(messages.size(), 4);
168 int toPrint = upTo;
169 112
170 if (hasFace) 113 if (hasFace)
171 { 114 {
172 g2.drawImage(face, tx+SPACER, ty-fh+SPACER, null); 115 g2.drawImage(face, Window.Default.getLeftX()+SPACER, ty-fh+SPACER, null);
173
174 tx += 48 + (SPACER*2);
175 } 116 }
176 117
177 for (int i=0;i<msgs;i++) 118 g2.drawImage(tr.render(upTo), Window.Default.getLeftX(), Window.Default.getTopY()+y, null);
178 {
179 String message = messages.get(i);
180 int fw = g2.getFontMetrics().stringWidth(message);
181
182 g2.setPaint(new TexturePaint(SystemGraphic.getTextColor(), new Rectangle(tx, ty, fw, fh)));
183 g2.drawString(message.substring(0, Math.min(toPrint, message.length())), tx, ty);
184
185 ty+=(SPACER+fh);
186
187 toPrint -= Math.min(toPrint, message.length());
188 }
189 119
190 if (upTo < num) 120 if (tr.isCascadingDone())
191 { 121 {
192 upTo+=3;
193 } else {
194 g2.drawImage(SystemGraphic.getDownArrow(), (Window.Default.getFullWidth(width)/2)-5, y+HEIGHT+SPACER+(bounceArrow ? 1 : 0), null); 122 g2.drawImage(SystemGraphic.getDownArrow(), (Window.Default.getFullWidth(width)/2)-5, y+HEIGHT+SPACER+(bounceArrow ? 1 : 0), null);
195 123
196 if (in.isElapsed()) 124 if (in.isElapsed())
@@ -202,20 +130,19 @@ public class MessageWindow implements Renderable {
202 130
203 private synchronized boolean pushEnter() 131 private synchronized boolean pushEnter()
204 { 132 {
205 if (upTo >= num) 133 if (tr.isCascadingDone())
206 { 134 {
207 int msgs = messages.size(); 135 int msgs = tr.numLines();
208 for (int i=0;i<Math.min(4, msgs);i++) 136 if (upTo >= (msgs-4))
209 { 137 {
210 messages.remove(0);
211 }
212
213 if (messages.size() > 0)
214 {
215 upTo = 0;
216 setLength();
217 } else {
218 return true; 138 return true;
139 } else {
140 upTo += 4;
141
142 if (upTo > msgs)
143 {
144 upTo = msgs;
145 }
219 } 146 }
220 } 147 }
221 148
diff --git a/src/com/fourisland/fourpuzzle/window/SystemGraphic.java b/src/com/fourisland/fourpuzzle/window/SystemGraphic.java index 75e2b45..aa0b593 100755 --- a/src/com/fourisland/fourpuzzle/window/SystemGraphic.java +++ b/src/com/fourisland/fourpuzzle/window/SystemGraphic.java
@@ -64,14 +64,19 @@ public class SystemGraphic {
64 return systemGraphic.getSubimage(sca.x, sca.y, sca.width, sca.height); 64 return systemGraphic.getSubimage(sca.x, sca.y, sca.width, sca.height);
65 } 65 }
66 66
67 public static BufferedImage getTextColor() 67 public static BufferedImage getTextColor(int color)
68 { 68 {
69 if (systemGraphic == null) 69 if (systemGraphic == null)
70 { 70 {
71 initalize(); 71 initalize();
72 } 72 }
73 73
74 return systemGraphic.getSubimage(0, 48, 16, 16); 74 if (color < 10)
75 {
76 return systemGraphic.getSubimage(color*16, 48, 16, 16);
77 } else {
78 return systemGraphic.getSubimage(color*16, 64, 16, 16);
79 }
75 } 80 }
76 81
77 public static BufferedImage getUpArrow() 82 public static BufferedImage getUpArrow()
diff --git a/src/com/fourisland/fourpuzzle/window/TextRenderer.java b/src/com/fourisland/fourpuzzle/window/TextRenderer.java new file mode 100644 index 0000000..f114c4d --- /dev/null +++ b/src/com/fourisland/fourpuzzle/window/TextRenderer.java
@@ -0,0 +1,306 @@
1/*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5
6package com.fourisland.fourpuzzle.window;
7
8import com.fourisland.fourpuzzle.Display;
9import com.fourisland.fourpuzzle.Game;
10import com.fourisland.fourpuzzle.util.PauseTimer;
11import java.awt.Graphics2D;
12import java.awt.Rectangle;
13import java.awt.TexturePaint;
14import java.awt.image.BufferedImage;
15import java.util.ArrayList;
16import java.util.HashMap;
17import java.util.List;
18import java.util.Map;
19import java.util.Vector;
20
21/**
22 *
23 * @author hatkirby
24 */
25public class TextRenderer {
26
27 private static final int SPACER = 4;
28
29 private boolean initalized = false;
30 private int width;
31 private List<LineOfText> messages = new ArrayList<LineOfText>();
32
33 public TextRenderer(int width)
34 {
35 this.width = width;
36 }
37
38 private boolean useEscapes = false;
39 public void setEscapes(boolean use)
40 {
41 if (initalized == true)
42 {
43 throw new IllegalStateException("Already initalized");
44 }
45
46 useEscapes = use;
47 }
48
49 private int indent = 0;
50 public void setIndent(int indent)
51 {
52 if (initalized == true)
53 {
54 throw new IllegalStateException("Already initalized");
55 }
56
57 this.indent = indent;
58 }
59
60 public void initalizeText(String message)
61 {
62 if (initalized == true)
63 {
64 throw new IllegalStateException("Already initalized");
65 }
66
67 int length = width - SPACER - indent;
68 int len = 0;
69 LineOfText temp = new LineOfText(message);
70
71 if (useEscapes)
72 {
73 for (int i=0; i<temp.length(); i++)
74 {
75 if (temp.toString().substring(i, i+1).equals("\\"))
76 {
77 for (MessageEscape escape : MessageEscape.values())
78 {
79 if (escape.match(temp.toString().substring(i)))
80 {
81 temp.addEscape(i, escape.getMatch(temp.toString().substring(i)));
82 temp = new LineOfText(escape.removeEscape(temp.toString()), temp.escapes);
83
84 break;
85 }
86 }
87 }
88 }
89
90 temp = new LineOfText(MessageEscape.removeEscapes(temp.toString()), temp.escapes);
91 }
92
93 while (!temp.toString().isEmpty())
94 {
95 while ((Display.getFontMetrics().stringWidth(temp.toString().substring(0, len)) < length) && (len < temp.length()))
96 {
97 len++;
98 }
99
100 if (len != temp.toString().length())
101 {
102 while ((!temp.toString().substring(len, len+1).equals(" ")) && (len > 0))
103 {
104 len--;
105 }
106 }
107
108 messages.add(temp.part(0, len));
109
110 if (len != temp.length())
111 {
112 temp = temp.part(len+1, temp.length());
113 } else {
114 break;
115 }
116
117 len = 0;
118 }
119
120 initalized = true;
121 }
122
123 int upTo = Integer.MIN_VALUE;
124 int num = 0;
125 int lastStart = Integer.MIN_VALUE+1;
126 PauseTimer pt = new PauseTimer(0);
127 public BufferedImage render(int start)
128 {
129 if (initalized == false)
130 {
131 throw new IllegalStateException("TextRenderer must be initalized prior to rendering");
132 }
133
134 if (lastStart != start)
135 {
136 num = 0;
137 for (int i=start;i<Math.min(messages.size(),start+4);i++)
138 {
139 num += messages.get(i).length();
140 }
141
142 lastStart = start;
143 upTo = 0;
144 }
145
146 BufferedImage temp = Display.createCanvas(width, Game.HEIGHT);
147 Graphics2D g = temp.createGraphics();
148 Display.setFont(g);
149
150 int currentColor = 0;
151
152 int fh = g.getFontMetrics().getHeight();
153 int ty = fh-(SPACER/2);
154 int toPrint = upTo;
155 int end = Math.min(messages.size(), start+4);
156
157 for (int i=start;i<end;i++)
158 {
159 LineOfText message = messages.get(i);
160 int tx = indent;
161 g.setPaint(new TexturePaint(SystemGraphic.getTextColor(currentColor), new Rectangle(0, ty, width, fh)));
162
163 for (int j=0;j<Math.min(toPrint, message.length());j++)
164 {
165 boolean breakout = false;
166 for (MessageEscapePair escape : message.getEscapes(j))
167 {
168 switch (escape.getMessageEscape())
169 {
170 case Color: currentColor = Integer.decode(escape.getMatchResult().group(1));
171 g.setPaint(new TexturePaint(SystemGraphic.getTextColor(currentColor), new Rectangle(0, ty, width, fh)));
172
173 break;
174
175 case Pause: pt.setTimer(10);
176 message.getEscapes(j).remove(escape);
177
178 breakout = true;
179 break;
180 }
181
182 if (breakout)
183 {
184 break;
185 }
186 }
187
188 g.drawString(message.toString().substring(j, j+1), tx, ty);
189
190 tx+=(g.getFontMetrics().stringWidth(message.toString().substring(j, j+1)));
191 }
192
193 ty+=(SPACER+fh);
194
195 toPrint -= Math.min(toPrint, message.length());
196 }
197
198 if (pt.isElapsed() && (upTo < num))
199 {
200 upTo+=3;
201 }
202
203 return temp;
204 }
205
206 public int numLines()
207 {
208 return messages.size();
209 }
210
211 public boolean isCascadingDone()
212 {
213 return (upTo >= num);
214 }
215
216}
217
218class LineOfText implements CharSequence
219{
220 String line;
221 Map<Integer, Vector<MessageEscapePair>> escapes = new HashMap<Integer, Vector<MessageEscapePair>>();
222 public LineOfText(String line)
223 {
224 this.line = line;
225 }
226
227 public LineOfText(String line, Map<Integer, Vector<MessageEscapePair>> escapes)
228 {
229 this.line = line;
230
231 for (int i=0; i<line.length(); i++)
232 {
233 if (escapes.containsKey(i))
234 {
235 for (MessageEscapePair escape : escapes.get(i))
236 {
237 addEscape(i, escape);
238 }
239 }
240 }
241 }
242
243 public void addEscape(int index, MessageEscapePair escape)
244 {
245 if (!escapes.containsKey(index))
246 {
247 escapes.put(index, new Vector<MessageEscapePair>());
248 }
249
250 escapes.get(index).add(escape);
251 }
252
253 public Vector<MessageEscapePair> getEscapes(int index)
254 {
255 if (!escapes.containsKey(index))
256 {
257 return new Vector<MessageEscapePair>();
258 } else {
259 return escapes.get(index);
260 }
261 }
262
263 public LineOfText part(int start, int end)
264 {
265 LineOfText temp = new LineOfText(line.substring(start, end));
266
267 for (int i=start; i<end; i++)
268 {
269 if (escapes.containsKey(i))
270 {
271 for (MessageEscapePair escape : escapes.get(i))
272 {
273 temp.addEscape(i, escape);
274 }
275 }
276 }
277
278 return temp;
279 }
280
281 @Override
282 public String toString()
283 {
284 return line;
285 }
286
287 public void setString(String message)
288 {
289 this.line = message;
290 }
291
292 public int length()
293 {
294 return line.length();
295 }
296
297 public char charAt(int index)
298 {
299 return line.charAt(index);
300 }
301
302 public CharSequence subSequence(int start, int end)
303 {
304 return line.subSequence(start, end);
305 }
306} \ No newline at end of file