1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package net
.multiphasicapps
.lcduidemo
;
12 import java
.util
.Random
;
13 import javax
.microedition
.lcdui
.Canvas
;
14 import javax
.microedition
.lcdui
.Display
;
15 import javax
.microedition
.lcdui
.Graphics
;
16 import javax
.microedition
.midlet
.MIDlet
;
17 import javax
.microedition
.midlet
.MIDletStateChangeException
;
20 * This is a MIDlet which simulates the old-style Mystify Your Mind
21 * screensaver from Windows 3.1.
28 /** The number of polygon points. */
29 public static final int NUM_POINTS
=
32 /** The number of shadows to draw. */
33 public static final int NUM_SHADOWS
=
36 /** The maximum line speed. */
37 public static final int MAX_SPEED
=
40 /** Use to detect way off coordinates. */
41 public static final int WAY_OFF
=
44 /** How oftens the colors shift. */
45 public static final int COLOR_SHIFT
=
48 /** The delay time. */
49 public static final int DELAY_TIME
=
52 /** Delay time in nanoseconds. */
53 public static final long DELAY_TIME_NS
= Mystify
.DELAY_TIME
* 1_000_000L
;
60 protected void destroyApp(boolean __uc
)
61 throws MIDletStateChangeException
70 protected void startApp()
71 throws MIDletStateChangeException
74 DemoCanvas cv
= new DemoCanvas();
77 cv
.addCommand(Exit
.command
);
78 cv
.setCommandListener(new Exit());
80 // Set display to the canvas
81 Display
.getDisplay(this).setCurrent(cv
);
85 * The demo canvas which does the animation.
89 public static final class DemoCanvas
92 /** Random number generator for bounces and such. */
93 protected final Random random
=
96 /** Points and their shadows. */
97 protected final Point
[][] points
=
98 new Point
[Mystify
.NUM_SHADOWS
][Mystify
.NUM_POINTS
];
101 protected final int[] colors
=
102 new int[Mystify
.NUM_SHADOWS
];
104 /** The direction of the points. */
105 protected final Point
[] direction
=
106 new Point
[Mystify
.NUM_POINTS
];
108 /** Update lock to prevent multiple threads updating at once. */
109 private volatile boolean _lockflag
;
111 /** The last time an update happened. */
112 private volatile long _nextnano
=
116 * Initializes the canvas state.
122 this.setTitle("Mystify Your Squirrels");
125 Point
[][] points
= this.points
;
127 // Generate random start points
128 Random random
= this.random
;
129 Point
[] start
= points
[0];
130 for (int i
= 0; i
< Mystify
.NUM_POINTS
; i
++)
131 start
[i
] = new Point(random
.nextInt(), random
.nextInt());
133 // Copy all the points to the shadow
134 for (int i
= 1; i
< Mystify
.NUM_SHADOWS
; i
++)
135 for (int j
= 0; j
< Mystify
.NUM_POINTS
; j
++)
136 points
[i
][j
] = new Point(start
[j
]);
138 // Initialize the color cycle
139 int[] colors
= this.colors
;
140 for (int i
= 0; i
< Mystify
.NUM_SHADOWS
; i
++)
141 colors
[i
] = random
.nextInt();
143 // Determine new directions for all the points
144 Point
[] direction
= this.direction
;
145 for (int i
= 0; i
< Mystify
.NUM_POINTS
; i
++)
146 direction
[i
] = this.__newDirection(new Point(),
147 random
.nextBoolean(), random
.nextBoolean());
149 // We do not draw over every pixel
150 this.setPaintMode(false);
158 public void paint(Graphics __g
)
161 int w
= this.getWidth(),
162 h
= this.getHeight();
164 // Needed for cycling
165 Random random
= this.random
;
167 // Needed for drawing
168 Point
[][] points
= this.points
;
169 Point
[] direction
= this.direction
;
170 int[] colors
= this.colors
;
172 // Used to limit update rate
173 long now
= System
.nanoTime(),
174 nextnano
= this._nextnano
;
176 // Draw every point, from older shadows to the newer shape
177 for (int i
= Mystify
.NUM_SHADOWS
- 1; i
>= 0; i
--)
179 Point
[] draw
= points
[i
];
181 // Update the state of the demo, but keep it consistent so
182 // that it is not always updating
183 if (i
== 0 && now
>= nextnano
)
185 // Only allow a single run to update this
190 lockflag
= this._lockflag
;
192 this._lockflag
= true;
195 // If we did hit a false, we can update
200 this.__updateState(w
, h
);
204 // Always clear the flag so another run can
206 this._lockflag
= false;
208 // Update some other time in the future
209 this._nextnano
= System
.nanoTime() +
210 Mystify
.DELAY_TIME_NS
;
214 // Set the color for this shadow
215 __g
.setColor(colors
[i
]);
217 // Draw all the points
218 for (int j
= 0; j
< Mystify
.NUM_POINTS
; j
++)
220 // Get A and B points
222 b
= draw
[(j
+ 1) % Mystify
.NUM_POINTS
];
225 __g
.drawLine(a
.x
, a
.y
, b
.x
, b
.y
);
229 // Request repaint to paint as fast as possible
234 * Gives a new direction for the point.
236 * @param __p The input point to get a new direction for.
237 * @param __px Positive X?
238 * @param __py Positive Y?
239 * @return {@code __p}
240 * @throws NullPointerException On null arguments.
243 private Point
__newDirection(Point __p
, boolean __px
, boolean __py
)
244 throws NullPointerException
247 throw new NullPointerException("NARG");
249 // Generate new speeds
250 Random random
= this.random
;
251 int x
= random
.nextInt(Mystify
.MAX_SPEED
) + 1,
252 y
= random
.nextInt(Mystify
.MAX_SPEED
) + 1;
269 * Updates the state of the demo.
271 * @param __w The width.
272 * @param __h The height.
275 private void __updateState(int __w
, int __h
)
277 // Needed for cycling
278 Random random
= this.random
;
280 // Base points to modify
281 Point
[] draw
= this.points
[0];
283 // Needed for drawing
284 Point
[][] points
= this.points
;
285 Point
[] direction
= this.direction
;
286 int[] colors
= this.colors
;
288 // Move all the old points and colors down
289 for (int j
= Mystify
.NUM_SHADOWS
- 2; j
>= 0; j
--)
291 points
[j
+ 1] = points
[j
];
292 colors
[j
+ 1] = colors
[j
];
295 // Allocate a new set of points offset in the directions
296 Point
[] place
= new Point
[Mystify
.NUM_POINTS
];
297 for (int j
= 0; j
< Mystify
.NUM_POINTS
; j
++)
299 // Get base coordinates
300 int newx
= draw
[j
].x
,
303 // Limit to the bounds of the screen. If a point is
304 // way off, just choose a random point on the
306 if (newx
< 0 || newx
>= __w
)
308 if (newx
< -Mystify
.WAY_OFF
|| newy
> __w
+ Mystify
.WAY_OFF
)
309 newx
= random
.nextInt((__w
> 0 ? __w
: 1));
314 else if (newx
>= __w
)
319 if (newy
< 0 || newy
>= __h
)
321 if (newy
< -Mystify
.WAY_OFF
|| newy
> __h
+ Mystify
.WAY_OFF
)
322 newy
= random
.nextInt((__h
> 0 ? __h
: 1));
327 else if (newy
>= __h
)
332 // Move point in the target direction
333 newx
+= direction
[j
].x
;
334 newy
+= direction
[j
].y
;
336 // Previous positive position?
337 boolean ppx
= (direction
[j
].x
>= 0),
338 ppy
= (direction
[j
].y
>= 0);
341 boolean defx
= (newx
<= 0 || newx
>= __w
),
342 defy
= (newy
<= 0 || newy
>= __h
);
345 this.__newDirection(direction
[j
],
346 ppx ^ defx
, ppy ^ defy
);
348 // Make sure the points are not on a bound!
361 int color
= colors
[j
];
362 byte r
= (byte)((color
& 0xFF0000) >>> 16),
363 g
= (byte)((color
& 0x00FF00) >>> 8),
364 b
= (byte)((color
& 0x0000FF));
366 // Cycle the colors depending on the direction of travel
367 r
+= (ppx ^ ppy ?
+Mystify
.COLOR_SHIFT
: -Mystify
.COLOR_SHIFT
);
368 g
+= (ppy
| ppy ?
-Mystify
.COLOR_SHIFT
: +Mystify
.COLOR_SHIFT
);
369 b
+= (ppx ^ ppy ?
-Mystify
.COLOR_SHIFT
: +Mystify
.COLOR_SHIFT
);
371 // Recombine the color
372 colors
[j
] = ((r
& 0xFF) << 16) |
377 place
[j
] = new Point(newx
, newy
);
380 // Use all these points
386 * Volatile point information.
390 public static final class Point
399 * Initializes the point.
408 * Initializes the point from another point.
410 * @param __p The point to copy.
411 * @throws NullPointerException On null arguments.
414 public Point(Point __p
)
415 throws NullPointerException
418 throw new NullPointerException("NARG");
425 * Initializes the point from the given coordinates.
427 * @param __x The X coordinate.
428 * @param __y The Y coordinate.
431 public Point(int __x
, int __y
)