選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 

1 行
7.8 KiB

  1. // // Neercs // #if defined HAVE_CONFIG_H # include "config.h" #endif #include "core.h" using namespace std; using namespace lol; #include "../neercs.h" #include "term.h" extern bool g_setup; Term::Term(ivec2 size) : m_pty(0), m_caca(caca_create_canvas(size.x, size.y)), m_size(size), m_title(0), m_bell(0), m_init(0), m_report_mouse(0), m_changed(0), m_time(0.f), m_debug(false) { #if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H m_pty = new Pty(); char const *shell = getenv("SHELL"); if (!shell) shell = "/bin/sh"; m_pty->Run(shell, size); #endif } void Term::TickGame(float seconds) { Entity::TickGame(seconds); #if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H if (!g_setup) { bool have_ctrl = Input::GetStatus(Key::LeftCtrl) || Input::GetStatus(Key::RightCtrl); bool have_shift = Input::GetStatus(Key::LeftShift) || Input::GetStatus(Key::RightShift); /* Check for standard ASCII keys */ for (int i = 0x0; i < 0x7f; ++i) { if (Input::WasPressed((Key::Value)i)) { if (have_ctrl && i >= 'a' && i <= 'z') { char c = i + 1 - 'a'; m_pty->WriteData(&c, 1); } else if (have_shift && i >= 'a' && i <= 'z') { char c = i + 'A' - 'a'; m_pty->WriteData(&c, 1); } else { char c = i; m_pty->WriteData(&c, 1); } } } /* Check for special keys */ static struct { Key::Value k; char const *str; int len; } const lut[] = { { Key::Up, "\033OA", 3 }, { Key::Down, "\033OB", 3 }, { Key::Right, "\033OC", 3 }, { Key::Left, "\033OD", 3 }, { Key::PageUp, "\033[5~", 4 }, { Key::PageDown, "\033[6~", 4 }, { Key::Home, "\033[1~", 4 }, { Key::Insert, "\033[2~", 4 }, { Key::Delete, "\033[3~", 4 }, { Key::End, "\033[4~", 4 }, #if 0 /* FIXME: disabled for now (used by the theme system */ { Key::F1, "\033[11~", 5 }, { Key::F2, "\033[12~", 5 }, { Key::F3, "\033[13~", 5 }, { Key::F4, "\033[14~", 5 }, { Key::F5, "\033[15~", 5 }, { Key::F6, "\033[17~", 5 }, { Key::F7, "\033[18~", 5 }, { Key::F8, "\033[19~", 5 }, { Key::F9, "\033[20~", 5 }, { Key::F10, "\033[21~", 5 }, { Key::F11, "\033[23~", 5 }, { Key::F12, "\033[24~", 5 }, #endif }; for (size_t i = 0; i < sizeof(lut) / sizeof(*lut); i++) { if (!have_ctrl && !have_shift) if (Input::WasPressed(lut[i].k)) m_pty->WriteData(lut[i].str, lut[i].len); } } m_time += seconds; if (m_pty->IsEof()) { /* FIXME: we could do more interesting things here… */ Ticker::Shutdown(); } m_pty->SetWindowSize(ivec2(caca_get_canvas_width(m_caca), caca_get_canvas_height(m_caca))); /* This is the real terminal code */ size_t total = 0; for (;;) { char buf[BUFSIZ]; size_t current = m_pty->ReadData(buf, BUFSIZ); if (current <= 0) break; /* FIXME: by the time we're finished decoding the ANSI data, some * new data may be available. We need to avoid reading it because * it's time rendering the canvas isntead. */ size_t processed = ReadAnsi(buf, current); if (processed < current) m_pty->UnreadData(buf + processed, current - processed); total += processed; if (processed == 0) break; /* FIXME: when do we know when to stop? If we read too much * data, some of our frames will not be rendered because they'll * be overwritten by new data. If we don't read enough, we will * start rendering even if a frame isn't finished. */ if (total > 12000) break; } /* Some fancy shit if we press F3 */ if (Input::WasPressed(Key::F3)) m_debug = !m_debug; if (m_debug) { DrawFancyShit(); } #else /* Unsupported platform - draw some fancy shit instead */ m_time += seconds; DrawFancyShit(); #endif } void Term::TickDraw(float seconds) { Entity::TickDraw(seconds); } Term::~Term() { #if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H delete m_pty; #endif caca_free_canvas(m_caca); } /* * XXX: fancy shit below */ static uint32_t hex_color(float r, float g, float b) { return ((uint32_t)(r * 15.99f) << 8) | ((uint32_t)(g * 15.99f) << 4) | (uint32_t)(b * 15.99f); } void Term::DrawFancyShit() { /* draw something awesome */ int bg_color = 0x000; int w = caca_get_canvas_width(m_caca); int h = caca_get_canvas_height(m_caca); caca_set_color_argb(m_caca, 0xfff, bg_color); caca_clear_canvas(m_caca); caca_set_color_argb(m_caca, 0x0f0, bg_color); for(int i = 0; i < h; i++) { float a = F_PI / 180 * i * 16 + m_time * 4; float b = F_PI / 180 * i * 12; int x = w / 2 - 14 + w / 4 * lol::cos(a) + w / 4 * lol::sin(b); caca_put_str(m_caca, x, i, "LOL WUT! NEERCS SI TEH RULEZ"); } caca_set_color_argb(m_caca, 0x444, bg_color); for(int i = 0; i < w; i++) { float a = m_time * 1 + F_PI / 180 * i * 8; float b = m_time * -2 + F_PI / 180 * i * 5; int y = h / 2 + h / 4 * lol::cos(a) + h / 4 * lol::sin(b); 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); caca_draw_line(m_caca, i, y - 1, i, y + 1,'%'); } /* __ _________ ______ ______ ______ ______ / \/ / __ > __ > __ > ___// ___/ \x0a9 / / ____/ ____/ __ < <____\___ \ /__/\__/\_______________/ \________________\ */ int logo_x = (w - 46) / 2; int logo_y = h / 2 - 2; caca_set_color_argb(m_caca, 0xbac, bg_color); caca_put_str(m_caca, logo_x + 3, logo_y ,"__ _________ ______ ______ ______ ______"); caca_put_str(m_caca, logo_x + 2, logo_y + 1, "/ \\/ / __ > __ > __ > ___// ___/ \x0a9"); caca_put_str(m_caca, logo_x + 1, logo_y + 2, "/ / ____/ ____/ __ < <____\\___ \\"); caca_put_str(m_caca, logo_x , logo_y + 3, "/__/\\__/\\_______________/ \\________________\\"); caca_set_color_argb(m_caca, 0x269, bg_color); caca_put_str(m_caca, logo_x + 5, logo_y + 5, "ALL YOUR TERMINALS ARE BELONG TO US"); caca_set_color_argb(m_caca, 0x777, bg_color); caca_printf(m_caca, 2, h - 3, "W=%i", w); caca_printf(m_caca, 2, h - 2, "H=%i", h); caca_set_color_argb(m_caca, hex_color(0.6f + 0.4f * lol::cos(m_time * 2), 0.2f, 0.2f), bg_color); caca_put_str(m_caca, w - 12, h - 2, "CACA RULEZ"); /*_______ / /| /______/ | | | | | :D | / |______|/ */ /* int lolcube_x = w - 12; int lolcube_y = h - 8; caca_set_color_argb(m_caca, 0x777, bg_color); caca_put_str(m_caca, lolcube_x + 2, lolcube_y , "_______"); caca_put_str(m_caca, lolcube_x + 1, lolcube_y + 1, "/ /|"); caca_put_str(m_caca, lolcube_x , lolcube_y + 2, "/______/ |"); caca_put_str(m_caca, lolcube_x , lolcube_y + 3, "| | |"); caca_put_str(m_caca, lolcube_x , lolcube_y + 4, "| :D | /"); caca_put_str(m_caca, lolcube_x , lolcube_y + 5, "|______|/"); */ caca_set_color_argb(m_caca, 0x777, bg_color); caca_put_str(m_caca, 0, 0, "rez@lol:~/code/neercs/"); }