1
0

SerialSpammer.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package de.nplusc.izc.MegatronBridge;
  2. import com.fazecast.jSerialComm.SerialPort;
  3. import java.io.*;
  4. import java.util.Arrays;
  5. import java.util.LinkedList;
  6. import java.util.Queue;
  7. enum NextChunkAction
  8. {
  9. WAIT,
  10. REPEAT,
  11. CONTINUE,
  12. FINISHED
  13. }
  14. public class SerialSpammer
  15. {
  16. private InputStream in = null;
  17. private OutputStream o = null;
  18. private NextChunkAction nextChunkReady = NextChunkAction.WAIT;
  19. private int waitCtr = 0;
  20. private Object workaround = new Object();
  21. private int streampointer = 0;
  22. private Queue<CommandQueueItem> queue= new LinkedList<>();
  23. private boolean startedStreamPlayback = false;
  24. public Queue<CommandQueueItem> getQueue()
  25. {
  26. return queue;
  27. }
  28. private final char[] hex = "0123456789ABCDEF".toCharArray();
  29. private byte[] streamfile = null;
  30. public SerialSpammer(String comPortName)
  31. {
  32. System.out.println("Gobblygob");
  33. int sendOffset = 0;
  34. SerialPort comPort = SerialPort.getCommPort(comPortName);
  35. comPort.openPort();
  36. comPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
  37. in = comPort.getInputStream();
  38. o = comPort.getOutputStream();
  39. new Thread(()->
  40. {
  41. System.out.println("MunchMunchMunch");
  42. try
  43. {
  44. while (true)
  45. {
  46. if(in.available()<1)
  47. {
  48. continue;
  49. }
  50. int read = in.read();
  51. if (read == '~')
  52. {
  53. System.out.println("RSME");
  54. nextChunkReady = NextChunkAction.CONTINUE;
  55. synchronized (workaround)
  56. {
  57. System.out.println("POKE");
  58. workaround.notify();
  59. }
  60. }
  61. if (read == '<')
  62. {
  63. nextChunkReady = NextChunkAction.REPEAT;
  64. synchronized (workaround)
  65. {
  66. System.out.println("POKE");
  67. workaround.notify();
  68. }
  69. }
  70. System.out.write(read);
  71. System.out.flush();
  72. }
  73. }
  74. catch (IOException e)
  75. {
  76. e.printStackTrace();
  77. }
  78. }).start();
  79. new Thread(()->
  80. {
  81. while(true)
  82. {
  83. CommandQueueItem itm = queue.poll();
  84. if(itm != null)
  85. {
  86. switch (itm.type)
  87. {
  88. case ServoAction:
  89. if(itm.argument>15||itm.argument<0)
  90. {
  91. break;
  92. }
  93. try
  94. {
  95. o.write('*');
  96. o.write('S');
  97. o.write(hex[itm.argument]);
  98. o.write('G');
  99. } catch (IOException e)
  100. {
  101. e.printStackTrace();
  102. }
  103. break;
  104. case OnboardAudio:
  105. if(itm.argument>15||itm.argument<0)
  106. {
  107. break;
  108. }
  109. try
  110. {
  111. o.write('*');
  112. o.write('T');
  113. o.write(hex[itm.argument]);
  114. o.write('G');
  115. } catch (IOException e)
  116. {
  117. e.printStackTrace();
  118. }
  119. break;
  120. case CustomAudio:
  121. if(itm.argument<0)
  122. {
  123. break;
  124. }
  125. boolean wiggleMouth = false;
  126. if(itm.argument>0xFFFF)
  127. {
  128. wiggleMouth=true;
  129. itm.argument&=0xFFFF;
  130. }
  131. System.out.println(itm.argument);
  132. LinkedList<Character> reverser = new LinkedList<>();
  133. int arg = itm.argument;
  134. while(arg>0)
  135. {
  136. reverser.add(hex[arg%16]);
  137. arg>>=4;
  138. }
  139. try
  140. {
  141. o.write('*');
  142. while(true)
  143. {
  144. Character c = reverser.pollLast();
  145. if(c==null)
  146. {
  147. break;
  148. }
  149. o.write(c);
  150. System.out.println("CSEND="+c);
  151. }
  152. o.write(wiggleMouth?'V':'v');
  153. } catch (IOException e)
  154. {
  155. e.printStackTrace();
  156. }
  157. break;
  158. case StreamAudio:
  159. if(streamfile==null)
  160. {
  161. streamfile = itm.streamData;
  162. nextChunkReady=NextChunkAction.CONTINUE;
  163. synchronized (workaround)
  164. {
  165. System.out.println("POKE");
  166. workaround.notify();
  167. }
  168. }
  169. break;
  170. case MundwerkToggle:
  171. try
  172. {
  173. o.write('M');
  174. try
  175. {
  176. Thread.sleep(10);
  177. } catch (InterruptedException e)
  178. {
  179. e.printStackTrace();
  180. }
  181. } catch (IOException e)
  182. {
  183. e.printStackTrace();
  184. }
  185. break;
  186. case RawCommand:
  187. try
  188. {
  189. for(char c:itm.extendedArg.toCharArray())
  190. {
  191. o.write(c);
  192. }
  193. } catch (IOException e)
  194. {
  195. e.printStackTrace();
  196. }
  197. break;
  198. case VolumeSetter:
  199. try
  200. {
  201. for(int i=0;i<8;i++)
  202. {
  203. o.write('-');
  204. }
  205. for(int i=0;i<itm.argument;i++)
  206. {
  207. o.write('+');
  208. }
  209. } catch (IOException e)
  210. {
  211. e.printStackTrace();
  212. }
  213. break;
  214. }
  215. }
  216. if(streamfile!=null)
  217. {
  218. try{
  219. if(streampointer>=streamfile.length)
  220. {
  221. System.out.println("FINI");
  222. System.err.println("FINI");
  223. streamfile=null;
  224. startedStreamPlayback=false;
  225. }
  226. else
  227. {
  228. if((!startedStreamPlayback)&&(streampointer==8192||streampointer==streamfile.length))
  229. {
  230. System.out.println("PLAY");
  231. o.write('|');
  232. startedStreamPlayback=true;
  233. }
  234. switch(nextChunkReady)
  235. {
  236. case REPEAT:
  237. System.out.println("RTRY=("+streampointer+")");
  238. waitCtr=0;
  239. if(streampointer>=64)
  240. {
  241. streampointer-=64;
  242. }
  243. case CONTINUE:
  244. waitCtr=0;
  245. System.out.println("STR=("+streampointer+")");
  246. byte[] readbfr = Arrays.copyOfRange(streamfile,streampointer,streampointer+64);
  247. streampointer+=64;
  248. o.write('>');
  249. nextChunkReady=NextChunkAction.WAIT;
  250. o.write(readbfr);
  251. break;
  252. }
  253. synchronized (workaround)
  254. {
  255. if(nextChunkReady==NextChunkAction.WAIT)
  256. {
  257. System.out.println("GOTO WAIT");
  258. try
  259. {
  260. workaround.wait();
  261. } catch (InterruptedException e)
  262. {
  263. e.printStackTrace();
  264. }
  265. }
  266. }
  267. }
  268. }
  269. catch (IOException e)
  270. {
  271. System.out.println("Zöinks");
  272. e.printStackTrace();
  273. }
  274. }
  275. }
  276. }).start();
  277. }
  278. }