diff --git a/neercs/Makefile.am b/neercs/Makefile.am index 4aa1f64..f45fff3 100644 --- a/neercs/Makefile.am +++ b/neercs/Makefile.am @@ -8,6 +8,9 @@ neercs_SOURCES = \ \ $(old_sources) \ \ + term/term.cpp term/term.h \ + term/pty.cpp term/pty.h \ + \ video/render.cpp video/render.h \ video/text-render.cpp video/text-render.h \ video/simple.lolfx \ diff --git a/neercs/neercs.cpp b/neercs/neercs.cpp index f4ad3f7..0afa742 100644 --- a/neercs/neercs.cpp +++ b/neercs/neercs.cpp @@ -39,125 +39,23 @@ using namespace lol; #include "neercs.h" #include "video/render.h" -#define USE_OLD_NEERCS 0 - extern "C" { #include "old/neercs.h" } Neercs::Neercs(int argc, char **argv) - : m_ready(false), - m_caca(caca_create_canvas(10, 10)), - m_render(new Render(m_caca)), - m_time(0.f) + : m_term(new Term(ivec2(80, 25))), + m_render(new Render(m_term->GetCaca())), + m_ready(false) { + Ticker::Ref(m_term); Ticker::Ref(m_render); - -#if USE_OLD_NEERCS - m_buf = NULL; - m_screen_list = init_neercs(argc, argv); - if (!m_screen_list) - exit(-1); - m_screen_list->last_key_time = get_us(); -#endif -} - -int Neercs::hex_color(float r, float g, float b) -{ - return ((int)(r * 15.99f) << 8) | ((int)(g * 15.99f) << 4) | (int)(b * 15.99f); } void Neercs::TickGame(float seconds) { WorldEntity::TickGame(seconds); - -#if USE_OLD_NEERCS - mainloop_tick(&m_buf, m_screen_list); -#endif - - m_time += seconds; - - /* draw something awesome */ - int bg_color = 0x222; - 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, 0xfff, bg_color); - for(int i = 0; i < h; i++) - { - float a = M_PI / 180 * i * 16 + m_time * 4; - float b = M_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 + M_PI / 180 * i * 8; - float b = m_time * -2 + M_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, 0x8ac, bg_color); - //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 ), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 )), bg_color); - caca_put_str(m_caca, logo_x + 3, logo_y ,"__ _________ ______ ______ ______ ______"); - //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 1), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 1)), bg_color); - caca_put_str(m_caca, logo_x + 2, logo_y + 1, "/ \\/ / __ > __ > __ > ___// ___/ \x0a9"); - //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 2), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 2)), bg_color); - caca_put_str(m_caca, logo_x + 1, logo_y + 2, "/ / ____/ ____/ __ < <____\\___ \\"); - //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 3), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 3)), bg_color); - caca_put_str(m_caca, logo_x , logo_y + 3, "/__/\\__/\\_______________/ \\________________\\"); - caca_set_color_argb(m_caca, 0xdef, 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, 0x666, 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 / 2 - 5 + (w - 10) * lol::cos(m_time / 2); - int lolcube_y = h - 5 - abs ((h - 5) * lol::sin(m_time * 4)); - - caca_set_color_argb(m_caca, hex_color(0.75f + 0.25f * lol::sin(m_time * 2), 0.75f + 0.25f * lol::cos(m_time * 3), 0.75f + 0.25f * lol::sin(m_time * 5)), 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, 0xdef, bg_color); - caca_put_str(m_caca, 0, 0, "rez@lol:~/ sudo -s"); - caca_put_str(m_caca, 0, 1, "[sudo] password for rez:"); - caca_put_str(m_caca, 0, 2, "root@lol:~/ echo LOL"); - caca_put_str(m_caca, 0, 3, "LOL"); - caca_put_str(m_caca, 0, 4, "root@lol:~/"); } @@ -168,11 +66,7 @@ void Neercs::TickDraw(float seconds) Neercs::~Neercs() { -#if USE_OLD_NEERCS - free(m_buf); - free_screen_list(m_screen_list); -#endif - + Ticker::Unref(m_term); Ticker::Unref(m_render); } diff --git a/neercs/neercs.h b/neercs/neercs.h index 5e8b790..41c4289 100644 --- a/neercs/neercs.h +++ b/neercs/neercs.h @@ -10,6 +10,7 @@ #include #include "video/render.h" +#include "term/term.h" extern "C" { @@ -24,21 +25,15 @@ public: char const *GetName() { return ""; } - int hex_color(float r, float g, float b); - protected: virtual void TickGame(float seconds); virtual void TickDraw(float seconds); private: - bool m_ready; - caca_canvas_t *m_caca; + Term *m_term; Render *m_render; - float m_time; - /* Old neercs stuff */ - char *m_buf; - struct screen_list *m_screen_list; + bool m_ready; }; #endif // __NEERCS_H__ diff --git a/neercs/neercs.vcxproj b/neercs/neercs.vcxproj index 59fc132..a21aca4 100644 --- a/neercs/neercs.vcxproj +++ b/neercs/neercs.vcxproj @@ -41,6 +41,8 @@ + + @@ -69,6 +71,8 @@ + + diff --git a/neercs/term/pty.cpp b/neercs/term/pty.cpp new file mode 100644 index 0000000..5ea4718 --- /dev/null +++ b/neercs/term/pty.cpp @@ -0,0 +1,140 @@ +/* + * neercs console-based window manager + * Copyright (c) 2006-2012 Sam Hocevar + * All Rights Reserved + * + * This program is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H +# define _XOPEN_SOURCE +# include +# include +# include +# include +# include +# include +# if defined HAVE_PTY_H +# include /* for openpty and forkpty */ +# elif defined HAVE_UTIL_H +# include /* for OS X, OpenBSD and NetBSD */ +# elif defined HAVE_LIBUTIL_H +# include /* for FreeBSD */ +# endif +# include +# include +#endif + +#include "core.h" +#include "loldebug.h" + +using namespace std; +using namespace lol; + +#include "neercs.h" + +Pty::Pty(ivec2 size) + : m_size(size) +{ + ; +} + +Pty::~Pty() +{ + +} + +void Pty::Run(char const *command) +{ +#if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H + int fd; + pid_t pid; + + m_pid = 0; + m_fd = 0; + + pid = forkpty(&fd, NULL, NULL, NULL); + if (pid < 0) + { + fprintf(stderr, "forkpty() error\n"); + return; + } + else if (pid == 0) + { + SetWindowSize(m_size); + + /* putenv() eats the string, they need to be writable */ + static char tmp1[] = "CACA_DRIVER=slang"; + static char tmp2[] = "TERM=xterm"; + putenv(tmp1); + putenv(tmp2); + + m_argv[0] = command; + m_argv[1] = NULL; + /* The following const cast is valid. The Open Group Base + * Specification guarantees that the objects are completely + * constant. */ + execvp(command, const_cast(m_argv)); + fprintf(stderr, "execvp() error\n"); + return; + } + + fcntl(fd, F_SETFL, O_NDELAY); + + m_pid = pid; + m_fd = fd; +#endif +} + +void Pty::SetWindowSize(ivec2 size) +{ +#if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H + m_size = size; + + struct winsize ws; + + memset(&ws, 0, sizeof(ws)); + ws.ws_row = size.y; + ws.ws_col = size.x; + ioctl((int)m_fd, TIOCSWINSZ, (char *)&ws); +#endif +} + +#if 0 +int update_terms(struct screen_list *screen_list) +{ + int i, refresh = 0; + for (i = 0; i < screen_list->count; i++) + { + if (screen_list->screen[i]->total && !screen_list->dont_update_coords) + { + unsigned long int bytes; + + bytes = import_term(screen_list, + screen_list->screen[i], + screen_list->screen[i]->buf, + screen_list->screen[i]->total); + + if (bytes > 0) + { + screen_list->screen[i]->total -= bytes; + memmove(screen_list->screen[i]->buf, + screen_list->screen[i]->buf + bytes, + screen_list->screen[i]->total); + if (screen_list->screen[i]->visible || screen_list->modals.mini) + refresh = 1; + } + } + } + return refresh; +} +#endif + diff --git a/neercs/term/pty.h b/neercs/term/pty.h new file mode 100644 index 0000000..0f7a238 --- /dev/null +++ b/neercs/term/pty.h @@ -0,0 +1,25 @@ +// +// Neercs +// + +#if !defined __TERM_PTY_H__ +#define __TERM_PTY_H__ + +class Pty +{ +public: + Pty(ivec2 size); + ~Pty(); + + void Run(char const *command); + void SetWindowSize(ivec2 size); + +private: + uint64_t m_fd; + uint64_t m_pid; + char const *m_argv[2]; + ivec2 m_size; +}; + +#endif // __TERM_PTY_H__ + diff --git a/neercs/term/term.cpp b/neercs/term/term.cpp new file mode 100644 index 0000000..e0a6269 --- /dev/null +++ b/neercs/term/term.cpp @@ -0,0 +1,143 @@ +// +// Neercs +// + +#if defined HAVE_CONFIG_H +# include "config.h" +#endif + +#include "core.h" +#include "lolgl.h" + +using namespace std; +using namespace lol; + +#include "../neercs.h" +#include "term.h" + +Term::Term(ivec2 size) + : m_time(0.f) +{ + m_caca = caca_create_canvas(size.x, size.y); +} + +void Term::TickGame(float seconds) +{ + Entity::TickGame(seconds); + +#if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H + /* This is the real terminal code */ + /* XXX: for now we draw fancy shit */ + m_time += seconds; + DrawFancyShit(); +#else + /* Unsupported platform - draw some fancy shit instead */ + m_time += seconds; + DrawFancyShit(); +#endif +} + +void Term::TickDraw(float seconds) +{ + Entity::TickDraw(seconds); +} + +Term::~Term() +{ +} + +/* + * 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 = 0x222; + 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, 0xfff, bg_color); + for(int i = 0; i < h; i++) + { + float a = M_PI / 180 * i * 16 + m_time * 4; + float b = M_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 + M_PI / 180 * i * 8; + float b = m_time * -2 + M_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, 0x8ac, bg_color); + //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 ), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 )), bg_color); + caca_put_str(m_caca, logo_x + 3, logo_y ,"__ _________ ______ ______ ______ ______"); + //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 1), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 1)), bg_color); + caca_put_str(m_caca, logo_x + 2, logo_y + 1, "/ \\/ / __ > __ > __ > ___// ___/ \x0a9"); + //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 2), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 2)), bg_color); + caca_put_str(m_caca, logo_x + 1, logo_y + 2, "/ / ____/ ____/ __ < <____\\___ \\"); + //caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 3), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 3)), bg_color); + caca_put_str(m_caca, logo_x , logo_y + 3, "/__/\\__/\\_______________/ \\________________\\"); + caca_set_color_argb(m_caca, 0xdef, 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, 0x666, 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 / 2 - 5 + (w - 10) * lol::cos(m_time / 2); + int lolcube_y = h - 5 - abs ((h - 5) * lol::sin(m_time * 4)); + + caca_set_color_argb(m_caca, hex_color(0.75f + 0.25f * lol::sin(m_time * 2), 0.75f + 0.25f * lol::cos(m_time * 3), 0.75f + 0.25f * lol::sin(m_time * 5)), 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, 0xdef, bg_color); + caca_put_str(m_caca, 0, 0, "rez@lol:~/ sudo -s"); + caca_put_str(m_caca, 0, 1, "[sudo] password for rez:"); + caca_put_str(m_caca, 0, 2, "root@lol:~/ echo LOL"); + caca_put_str(m_caca, 0, 3, "LOL"); + caca_put_str(m_caca, 0, 4, "root@lol:~/"); +} + diff --git a/neercs/term/term.h b/neercs/term/term.h new file mode 100644 index 0000000..63f6abb --- /dev/null +++ b/neercs/term/term.h @@ -0,0 +1,34 @@ +// +// Neercs +// + +#if !defined __TERM_TERM_H__ +#define __TERM_TERM_H__ + +#include "term/pty.h" + +class Term : public Entity +{ +public: + Term(ivec2 size); + ~Term(); + + char const *GetName() { return ""; } + caca_canvas_t *GetCaca() { return m_caca; } + +protected: + virtual void TickGame(float seconds); + virtual void TickDraw(float seconds); + +private: + Pty *m_pty; + caca_canvas_t *m_caca; + ivec2 m_size; + + /* Mostly for fancy shit */ + void DrawFancyShit(); + float m_time; +}; + +#endif // __TERM_TERM_H__ +