Simple single-color 8x8x8 LED Cube with AVRs
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * cubeWorker.java
  3. *
  4. * Copyright 2011 Thomas Buck <xythobuz@me.com>
  5. * Copyright 2011 Max Nuding <max.nuding@gmail.com>
  6. * Copyright 2011 Felix Bäder <baeder.felix@gmail.com>
  7. *
  8. * This file is part of LED-Cube.
  9. *
  10. * LED-Cube is free software: you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * LED-Cube is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with LED-Cube. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. /*
  24. * This class handles one animation file. This file can contain
  25. * many animations, but has to be only 1Mbit in size (128*1024 Byte).
  26. */
  27. import java.util.ArrayList;
  28. import java.util.Arrays;
  29. import java.io.FileWriter;
  30. import java.io.File;
  31. import java.io.IOException;
  32. public class cubeWorker {
  33. // --------------------
  34. // Definitions
  35. // --------------------
  36. final int UP = 0;
  37. final int DOWN = 1;
  38. // --------------------
  39. // Fields
  40. // --------------------
  41. private ArrayList<Animation> animations = new ArrayList<Animation>();
  42. private int selectedAnimation = 0;
  43. private int selectedFrame = 0;
  44. private int framesRemaining = 2016; // (128 * 1024) / 65 = 2016,...
  45. private boolean changedState = false;
  46. // --------------------
  47. cubeWorker() {
  48. animations.add(new Animation());
  49. }
  50. cubeWorker(ArrayList<Animation> anims) {
  51. animations = anims;
  52. }
  53. // --------------------
  54. // Misc. Methods
  55. // --------------------
  56. // Returns how many animations are defined
  57. public int numOfAnimations() {
  58. return animations.size();
  59. }
  60. // Returns how many frames are in the current animation
  61. public int numOfFrames() {
  62. return animations.get(selectedAnimation).size();
  63. }
  64. // Tells how many Frames you can add until you reached 1 Mbit...
  65. public int framesRemaining() {
  66. return framesRemaining;
  67. }
  68. // --------------------
  69. // Animation Specific
  70. // --------------------
  71. // Selects an animation on wich the animation specific functions operate
  72. // Returns -1 if it does not exist, else its index
  73. public int selectAnimation(int index) {
  74. if (animations.size() <= index) {
  75. return -1;
  76. } else {
  77. selectedAnimation = index;
  78. return index;
  79. }
  80. }
  81. // Adds a new Animation
  82. // Returns id if ok, -1 if error or not enough space for
  83. // another animation
  84. public int addAnimation() {
  85. changedState = true;
  86. if (framesRemaining <= 0) {
  87. return -1;
  88. } else {
  89. int s = animations.size();
  90. animations.add(s + 1, new Animation());
  91. return s;
  92. }
  93. }
  94. // Removes an animation
  95. public void removeAnimation() {
  96. changedState = true;
  97. animations.remove(selectedAnimation);
  98. selectedAnimation = 0;
  99. }
  100. public String getAnimationName() {
  101. return animations.get(selectedAnimation).getName();
  102. }
  103. public void setAnimationName(String s) {
  104. changedState = true;
  105. animations.get(selectedAnimation).setName(s);
  106. }
  107. public void moveAnimation(int dir) {
  108. changedState = true;
  109. if (dir == UP){
  110. //animation moved up
  111. if (selectedAnimation > 0) {
  112. Animation tmp = animations.get(selectedAnimation);
  113. animations.set(selectedAnimation, animations.get(selectedAnimation - 1));
  114. animations.set(selectedAnimation - 1, tmp);
  115. }
  116. } else if (dir == DOWN){
  117. //animation moved down
  118. if (selectedAnimation < (animations.size() - 1)) {
  119. Animation tmp = animations.get(selectedAnimation);
  120. animations.set(selectedAnimation, animations.get(selectedAnimation + 1));
  121. animations.set(selectedAnimation + 1, tmp);
  122. }
  123. }
  124. }
  125. // --------------------
  126. // Frame Specific
  127. // --------------------
  128. // Selects an animation on wich the frame specific functions operate
  129. // Returns -1 if it does not exist, else its index
  130. public int selectFrame(int index) {
  131. if (animations.get(selectedAnimation).size() <= index) {
  132. return -1;
  133. } else {
  134. selectedFrame = index;
  135. return index;
  136. }
  137. }
  138. public String getFrameName() {
  139. return animations.get(selectedAnimation).get(selectedFrame).getName();
  140. }
  141. public void setFrameName(String s) {
  142. changedState = true;
  143. animations.get(selectedAnimation).get(selectedFrame).setName(s);
  144. }
  145. // Adds a Frame to the current animation.
  146. // Returns id if okay, -1 if error
  147. public int addFrame() {
  148. changedState = true;
  149. if (framesRemaining <= 0) {
  150. return -1;
  151. }
  152. framesRemaining--;
  153. int s = animations.get(selectedAnimation).size();
  154. animations.get(selectedAnimation).add(s);
  155. return s;
  156. }
  157. // Remove the frame
  158. public void removeFrame() {
  159. changedState = true;
  160. animations.get(selectedAnimation).remove(selectedFrame);
  161. selectedFrame = 0;
  162. }
  163. // Returns array with 64 bytes with led values
  164. public byte[] getFrame() {
  165. return animations.get(selectedAnimation).get(selectedFrame).getData();
  166. }
  167. public void setFrame(byte[] data) {
  168. changedState = true;
  169. animations.get(selectedAnimation).get(selectedFrame).setData(data);
  170. }
  171. // Frame duration in 1/24th of a second
  172. public byte getFrameTime() {
  173. return animations.get(selectedAnimation).get(selectedFrame).getTime();
  174. }
  175. public void setFrameTime(byte time) {
  176. changedState = true;
  177. animations.get(selectedAnimation).get(selectedFrame).setTime(time);
  178. }
  179. public void moveFrame(int dir){
  180. changedState = true;
  181. if (dir == UP){
  182. // frame moved up
  183. if (selectedFrame > 0) {
  184. AFrame tmp = animations.get(selectedAnimation).get(selectedFrame);
  185. animations.get(selectedAnimation).set(animations.get(selectedAnimation).get(selectedFrame - 1), selectedFrame);
  186. animations.get(selectedAnimation).set(tmp, selectedFrame - 1);
  187. selectedFrame--;
  188. }
  189. } else if (dir == DOWN){
  190. // frame moved down
  191. if (selectedFrame < (animations.get(selectedAnimation).size() - 1)) {
  192. AFrame tmp = animations.get(selectedAnimation).get(selectedFrame);
  193. animations.get(selectedAnimation).set(animations.get(selectedAnimation).get(selectedFrame + 1), selectedFrame);
  194. animations.get(selectedAnimation).set(tmp, selectedFrame + 1);
  195. selectedFrame++;
  196. }
  197. }
  198. }
  199. // --------------------
  200. // File Specific
  201. // --------------------
  202. // Loads an animation file into this object
  203. public int loadState(String path) {
  204. changedState = false;
  205. return 0;
  206. }
  207. // Saves the state of this object in an animation file
  208. public int saveState(String path) {
  209. changedState = false;
  210. AnimationUtility.writeFile(path, animations);
  211. if (AnimationUtility.getLastError() != null) {
  212. System.out.println(AnimationUtility.getLastError());
  213. return -1;
  214. }
  215. return 0;
  216. }
  217. // Returns true if last saved state != current state
  218. public boolean changedStateSinceSave() {
  219. return changedState;
  220. }
  221. // --------------------
  222. // Serial Port Specific
  223. // --------------------
  224. // sends state of object to led cube
  225. public int uploadState(String port) {
  226. return 0;
  227. }
  228. // loads all state from the cube into this object
  229. public int downloadState(String port) {
  230. return 0;
  231. }
  232. public String[] getSerialPorts() {
  233. String[] sPorts = { "Select serial port..." }; // Has to be the first entry
  234. return sPorts;
  235. }
  236. // --------------------
  237. }
  238. class AnimationUtility {
  239. private static String lastError = null;
  240. public static ArrayList<Animation> readFile(String path) {
  241. return null;
  242. }
  243. public static void writeFile(String path, ArrayList<Animation> animations) {
  244. File f = new File(path);
  245. if (f.exists()) {
  246. try {
  247. f.delete();
  248. } catch (Exception e) {
  249. lastError = e.toString();
  250. return;
  251. }
  252. }
  253. FileWriter output = null;
  254. try {
  255. output = new FileWriter(f);
  256. for (int i = 0; i < animations.size(); i++) {
  257. writeAnimation(animations.get(i), output);
  258. }
  259. } catch (Exception e) {
  260. lastError = e.toString();
  261. return;
  262. } finally {
  263. if (output != null) {
  264. try {
  265. output.close();
  266. } catch (Exception e) {
  267. lastError = e.toString();
  268. }
  269. }
  270. }
  271. }
  272. public static String getLastError() {
  273. String tmp = lastError;
  274. lastError = null;
  275. return tmp;
  276. }
  277. private static void writeAnimation(Animation anim, FileWriter f) throws IOException {
  278. f.write(anim.getName() + "\n");
  279. for (int i = 0; i < anim.size(); i++) {
  280. writeFrame(anim.get(i), f);
  281. }
  282. f.write("\n");
  283. }
  284. private static void writeFrame(AFrame fr, FileWriter f) throws IOException {
  285. for (int i = 0; i < 8; i++) {
  286. writeLayer(fr.getLayer(i), f);
  287. }
  288. f.write(Integer.toString( (fr.getTime() & 0xff) + 0x100, 16).substring(1) + "\n");
  289. }
  290. private static void writeLayer(byte[] l, FileWriter f) throws IOException {
  291. String hex = "";
  292. for (int i = 0; i < l.length; i++) {
  293. hex += Integer.toString( (l[i] & 0xff) + 0x100, 16).substring(1);
  294. }
  295. hex += "\n";
  296. f.write(hex);
  297. }
  298. }
  299. class AFrame {
  300. private byte[] data = new byte[64];
  301. private byte duration = 1;
  302. private String name = "Frame";
  303. String getName() {
  304. return name;
  305. }
  306. void setName(String s) {
  307. name = s;
  308. }
  309. void setData(byte[] d) {
  310. data = d;
  311. }
  312. byte[] getData() {
  313. return data;
  314. }
  315. void setTime(byte t) {
  316. duration = t;
  317. }
  318. byte getTime() {
  319. return duration;
  320. }
  321. byte[] getLayer(int i) {
  322. return Arrays.copyOfRange(data, (i * 8), (i * 8) + 8);
  323. }
  324. }
  325. class Animation {
  326. private ArrayList<AFrame> frames = new ArrayList<AFrame>();
  327. private int lastFrameIndex = 0;
  328. private String name = "Animation";
  329. String getName() {
  330. return name;
  331. }
  332. void setName(String s) {
  333. name = s;
  334. }
  335. AFrame get(int i) {
  336. try {
  337. return frames.get(i);
  338. } catch (IndexOutOfBoundsException e) {
  339. System.out.println(e.toString());
  340. return null;
  341. }
  342. }
  343. void set(AFrame f, int i) {
  344. if (lastFrameIndex <= i) {
  345. try {
  346. frames.set(i, f);
  347. } catch (IndexOutOfBoundsException e) {
  348. System.out.println(e.toString());
  349. }
  350. }
  351. }
  352. void remove(int i) {
  353. try {
  354. frames.remove(i);
  355. } catch (IndexOutOfBoundsException e) {
  356. System.out.println(e.toString());
  357. }
  358. }
  359. void add(int i) {
  360. try {
  361. frames.add(i, new AFrame());
  362. lastFrameIndex++;
  363. } catch (IndexOutOfBoundsException e) {
  364. System.out.println(e.toString());
  365. }
  366. }
  367. int size() {
  368. return frames.size();
  369. }
  370. }