Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

267 linhas
7.8 KiB

  1. //
  2. // Neercs
  3. //
  4. #if defined HAVE_CONFIG_H
  5. # include "config.h"
  6. #endif
  7. #include "core.h"
  8. using namespace std;
  9. using namespace lol;
  10. #include "../neercs.h"
  11. #include "term.h"
  12. extern bool g_setup;
  13. Term::Term(ivec2 size)
  14. : m_pty(0),
  15. m_caca(caca_create_canvas(size.x, size.y)),
  16. m_size(size),
  17. m_title(0),
  18. m_bell(0),
  19. m_init(0),
  20. m_report_mouse(0),
  21. m_changed(0),
  22. m_time(0.f),
  23. m_debug(false)
  24. {
  25. #if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H
  26. m_pty = new Pty();
  27. char const *shell = getenv("SHELL");
  28. if (!shell)
  29. shell = "/bin/sh";
  30. m_pty->Run(shell, size);
  31. #endif
  32. }
  33. void Term::TickGame(float seconds)
  34. {
  35. Entity::TickGame(seconds);
  36. #if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H
  37. #if 0
  38. if (!g_setup)
  39. {
  40. bool have_ctrl = Input::GetStatus(Key::LeftCtrl)
  41. || Input::GetStatus(Key::RightCtrl);
  42. bool have_shift = Input::GetStatus(Key::LeftShift)
  43. || Input::GetStatus(Key::RightShift);
  44. /* Check for standard ASCII keys */
  45. for (int i = 0x0; i < 0x7f; ++i)
  46. {
  47. if (Input::WasPressed((Key::Value)i))
  48. {
  49. if (have_ctrl && i >= 'a' && i <= 'z')
  50. {
  51. char c = i + 1 - 'a';
  52. m_pty->WriteData(&c, 1);
  53. }
  54. else if (have_shift && i >= 'a' && i <= 'z')
  55. {
  56. char c = i + 'A' - 'a';
  57. m_pty->WriteData(&c, 1);
  58. }
  59. else
  60. {
  61. char c = i;
  62. m_pty->WriteData(&c, 1);
  63. }
  64. }
  65. }
  66. /* Check for special keys */
  67. static struct { Key::Value k; char const *str; int len; } const lut[] =
  68. {
  69. { Key::Up, "\033OA", 3 },
  70. { Key::Down, "\033OB", 3 },
  71. { Key::Right, "\033OC", 3 },
  72. { Key::Left, "\033OD", 3 },
  73. { Key::PageUp, "\033[5~", 4 },
  74. { Key::PageDown, "\033[6~", 4 },
  75. { Key::Home, "\033[1~", 4 },
  76. { Key::Insert, "\033[2~", 4 },
  77. { Key::Delete, "\033[3~", 4 },
  78. { Key::End, "\033[4~", 4 },
  79. #if 0 /* FIXME: disabled for now (used by the theme system */
  80. { Key::F1, "\033[11~", 5 },
  81. { Key::F2, "\033[12~", 5 },
  82. { Key::F3, "\033[13~", 5 },
  83. { Key::F4, "\033[14~", 5 },
  84. { Key::F5, "\033[15~", 5 },
  85. { Key::F6, "\033[17~", 5 },
  86. { Key::F7, "\033[18~", 5 },
  87. { Key::F8, "\033[19~", 5 },
  88. { Key::F9, "\033[20~", 5 },
  89. { Key::F10, "\033[21~", 5 },
  90. { Key::F11, "\033[23~", 5 },
  91. { Key::F12, "\033[24~", 5 },
  92. #endif
  93. };
  94. for (size_t i = 0; i < sizeof(lut) / sizeof(*lut); i++)
  95. {
  96. if (!have_ctrl && !have_shift)
  97. if (Input::WasPressed(lut[i].k))
  98. m_pty->WriteData(lut[i].str, lut[i].len);
  99. }
  100. }
  101. #endif
  102. m_time += seconds;
  103. if (m_pty->IsEof())
  104. {
  105. /* FIXME: we could do more interesting things here… */
  106. Ticker::Shutdown();
  107. }
  108. m_pty->SetWindowSize(ivec2(caca_get_canvas_width(m_caca),
  109. caca_get_canvas_height(m_caca)));
  110. /* This is the real terminal code */
  111. size_t total = 0;
  112. for (;;)
  113. {
  114. char buf[BUFSIZ];
  115. size_t current = m_pty->ReadData(buf, BUFSIZ);
  116. if (current <= 0)
  117. break;
  118. /* FIXME: by the time we're finished decoding the ANSI data, some
  119. * new data may be available. We need to avoid reading it because
  120. * it's time rendering the canvas isntead. */
  121. size_t processed = ReadAnsi(buf, current);
  122. if (processed < current)
  123. m_pty->UnreadData(buf + processed, current - processed);
  124. total += processed;
  125. if (processed == 0)
  126. break;
  127. /* FIXME: when do we know when to stop? If we read too much
  128. * data, some of our frames will not be rendered because they'll
  129. * be overwritten by new data. If we don't read enough, we will
  130. * start rendering even if a frame isn't finished. */
  131. if (total > 12000)
  132. break;
  133. }
  134. /* Some fancy shit if we press F3 */
  135. #if 0
  136. if (Input::WasPressed(Key::F3))
  137. m_debug = !m_debug;
  138. #endif
  139. if (m_debug)
  140. {
  141. DrawFancyShit();
  142. }
  143. #else
  144. /* Unsupported platform - draw some fancy shit instead */
  145. m_time += seconds;
  146. DrawFancyShit();
  147. #endif
  148. }
  149. void Term::TickDraw(float seconds, Scene &scene)
  150. {
  151. Entity::TickDraw(seconds, scene);
  152. }
  153. Term::~Term()
  154. {
  155. #if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H
  156. delete m_pty;
  157. #endif
  158. caca_free_canvas(m_caca);
  159. }
  160. /*
  161. * XXX: fancy shit below
  162. */
  163. static uint32_t hex_color(float r, float g, float b)
  164. {
  165. return ((uint32_t)(r * 15.99f) << 8) |
  166. ((uint32_t)(g * 15.99f) << 4) |
  167. (uint32_t)(b * 15.99f);
  168. }
  169. void Term::DrawFancyShit()
  170. {
  171. /* draw something awesome */
  172. int bg_color = 0x000;
  173. int w = caca_get_canvas_width(m_caca);
  174. int h = caca_get_canvas_height(m_caca);
  175. caca_set_color_argb(m_caca, 0xfff, bg_color);
  176. caca_clear_canvas(m_caca);
  177. caca_set_color_argb(m_caca, 0x0f0, bg_color);
  178. for(int i = 0; i < h; i++)
  179. {
  180. float a = F_PI / 180 * i * 16 + m_time * 4;
  181. float b = F_PI / 180 * i * 12;
  182. int x = w / 2 - 14 + w / 4 * lol::cos(a) + w / 4 * lol::sin(b);
  183. caca_put_str(m_caca, x, i, "LOL WUT! NEERCS SI TEH RULEZ");
  184. }
  185. caca_set_color_argb(m_caca, 0x444, bg_color);
  186. for(int i = 0; i < w; i++)
  187. {
  188. float a = m_time * 1 + F_PI / 180 * i * 8;
  189. float b = m_time * -2 + F_PI / 180 * i * 5;
  190. int y = h / 2 + h / 4 * lol::cos(a) + h / 4 * lol::sin(b);
  191. caca_set_color_argb(m_caca, hex_color(0.25f + 0.5f / w * i - 0.25f / h * y, 0.25f, 0.25f + 0.25f / w * i + 0.25f / h * y), bg_color);
  192. caca_draw_line(m_caca, i, y - 1, i, y + 1,'%');
  193. }
  194. /* __ _________ ______ ______ ______ ______
  195. / \/ / __ > __ > __ > ___// ___/ \x0a9
  196. / / ____/ ____/ __ < <____\___ \
  197. /__/\__/\_______________/ \________________\ */
  198. int logo_x = (w - 46) / 2;
  199. int logo_y = h / 2 - 2;
  200. caca_set_color_argb(m_caca, 0xbac, bg_color);
  201. caca_put_str(m_caca, logo_x + 3, logo_y ,"__ _________ ______ ______ ______ ______");
  202. caca_put_str(m_caca, logo_x + 2, logo_y + 1, "/ \\/ / __ > __ > __ > ___// ___/ \x0a9");
  203. caca_put_str(m_caca, logo_x + 1, logo_y + 2, "/ / ____/ ____/ __ < <____\\___ \\");
  204. caca_put_str(m_caca, logo_x , logo_y + 3, "/__/\\__/\\_______________/ \\________________\\");
  205. caca_set_color_argb(m_caca, 0x269, bg_color);
  206. caca_put_str(m_caca, logo_x + 5, logo_y + 5, "ALL YOUR TERMINALS ARE BELONG TO US");
  207. caca_set_color_argb(m_caca, 0x777, bg_color);
  208. caca_printf(m_caca, 2, h - 3, "W=%i", w);
  209. caca_printf(m_caca, 2, h - 2, "H=%i", h);
  210. caca_set_color_argb(m_caca, hex_color(0.6f + 0.4f * lol::cos(m_time * 2), 0.2f, 0.2f), bg_color);
  211. caca_put_str(m_caca, w - 12, h - 2, "CACA RULEZ");
  212. /*_______
  213. / /|
  214. /______/ |
  215. | | |
  216. | :D | /
  217. |______|/
  218. */
  219. /*
  220. int lolcube_x = w - 12;
  221. int lolcube_y = h - 8;
  222. caca_set_color_argb(m_caca, 0x777, bg_color);
  223. caca_put_str(m_caca, lolcube_x + 2, lolcube_y , "_______");
  224. caca_put_str(m_caca, lolcube_x + 1, lolcube_y + 1, "/ /|");
  225. caca_put_str(m_caca, lolcube_x , lolcube_y + 2, "/______/ |");
  226. caca_put_str(m_caca, lolcube_x , lolcube_y + 3, "| | |");
  227. caca_put_str(m_caca, lolcube_x , lolcube_y + 4, "| :D | /");
  228. caca_put_str(m_caca, lolcube_x , lolcube_y + 5, "|______|/");
  229. */
  230. caca_set_color_argb(m_caca, 0x777, bg_color);
  231. caca_put_str(m_caca, 0, 0, "rez@lol:~/code/neercs/");
  232. }