source: trunk/tools/neercs/term/term.cpp @ 2278

Last change on this file since 2278 was 2177, checked in by rez, 8 years ago

NEERCS: changed copper base color to do not disturb sam white terminal :)

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