source: trunk/src/curses/curses_terminal.cc @ 521

Last change on this file since 521 was 520, checked in by epyon, 9 years ago
  • ecs updates
  • animation updates
  • ragdoll manager
  • lua has own random engine
  • several minor fixes
  • particle engine/particle group
  • shitload of other stuff
  • bullet world
File size: 4.8 KB
Line 
1// Copyright (C) 2013-2015 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7#include "nv/curses/curses_terminal.hh"
8
9#include "nv/core/time.hh"
10#include "nv/lib/curses.hh"
11
12using namespace nv;
13
14curses_terminal::curses_terminal( dimension size ) : terminal( size )
15{
16        load_curses_library();
17        m_screen = initscr();
18        raw();
19        cbreak();
20        noecho();
21
22        nodelay  ( static_cast<WINDOW*>( m_screen ), true );
23        intrflush( static_cast<WINDOW*>( m_screen ), false );
24        keypad   ( static_cast<WINDOW*>( m_screen ), true );
25
26        start_color();
27        resize_term( size.y, size.x );
28        PDC_save_key_modifiers( true );
29
30        for ( short i = 0; i < 64; ++i )
31                init_pair( i+1, i % 8, i / 8 );
32
33        clear();
34        refresh();   
35        curs_set(1);
36
37        m_update_needed = false;
38}
39
40void curses_terminal::update()
41{
42        if (m_update_needed)
43        {
44                refresh();
45                m_update_needed = false;
46        }
47}
48
49void curses_terminal::print( position p, term_color fgcolor, term_color bgcolor, char ch )
50{
51        uint32 fcolor = fgcolor.get_color();
52        uint32 bcolor = ( bgcolor.get_color() % 8 ) * 8;
53        m_update_needed = true;
54        chtype attr = static_cast<chtype>( ( fcolor > 7 ? fcolor - 7 + bcolor : fcolor + bcolor + 1 ) << 24 );
55        if ( fcolor > 7 ) attr = attr | 0x00800000ul;
56        attrset(attr);
57        mvaddch( p.y-1, p.x-1, chtype(ch) );
58        ::move( m_cursor.y-1, m_cursor.x-1 );
59}
60
61void curses_terminal::clear( rectangle r, term_color fgcolor, term_color bgcolor )
62{
63        uint32 fcolor = fgcolor.get_color();
64        uint32 bcolor = ( bgcolor.get_color() % 8 ) * 8;
65        chtype attr = static_cast<chtype>( ( fcolor > 7 ? fcolor - 7 + bcolor : fcolor + bcolor + 1 ) << 24 );
66        if ( fcolor > 7 ) attr = attr | 0x00800000ul;
67        attrset( attr );
68        for ( int x = r.ul.x-1; x <= r.lr.x-1; ++x )
69                for ( int y = r.ul.y-1; y <= r.lr.y-1; ++y )
70                        mvaddch( y, x, ' ' );
71}
72
73void curses_terminal::clear()
74{
75        m_update_needed = true;
76        ::clear();
77        ::move( m_cursor.y-1, m_cursor.x-1 );
78}
79
80bool curses_terminal::poll( io_event& kevent )
81{
82        // Sleep so we don't get 100% processor usage
83        sleep(10);
84
85        // Get value from curses
86        int result = wgetch( static_cast<WINDOW*>( m_screen ) );
87
88        // If value is err, return none event
89        if ( result == -1 )
90        {
91                return false;
92        }
93
94        // Zero the fields
95        kevent.type        = EV_KEY;
96        kevent.key.pressed = true;
97        kevent.key.ascii   = 0;
98        kevent.key.code    = nv::KEY_NONE;
99        kevent.key.control = false;
100        kevent.key.shift   = false;
101
102        // if result is a typable char place it into the structure
103        if ( result >= 32 && result < 128 )
104        {
105                kevent.key.ascii = static_cast<nv::uchar8>(result);
106        }
107
108        // Check the control and shift states
109        // TODO: obviously there is an ERROR here :P
110        kevent.key.control = (PDC_get_key_modifiers() & 2) != 0;
111        kevent.key.shift   = (PDC_get_key_modifiers() & 2) != 0;
112
113        // if result is a typable char from the directly transformable ranges
114        if ( (result >= nv::KEY_A && result <= nv::KEY_Z) ||
115                (result >= nv::KEY_0 && result <= nv::KEY_9) ||
116                result == ' ' )
117        {
118                kevent.key.code = static_cast<nv::key_code>(result);
119        }
120
121        // if result is a typable char from the a..z range
122        if ( result >= nv::KEY_A + 32 && result <= nv::KEY_Z + 32 )
123        {
124                kevent.key.code = static_cast<nv::key_code>(result - 32);
125        }
126
127        // if result is a typable char from the 0..9 range
128        if ( result >= nv::KEY_0 && result <= nv::KEY_9 )
129        {
130                kevent.key.code = static_cast<nv::key_code>(result);
131        }
132
133        // if result is a typable char from the 0..9 range
134        if ( result >= 0x108 && result <= 0x108 + 12 )
135        {
136                kevent.key.code = static_cast<nv::key_code>( nv::KEY_F1 + result - 0x108 - 1 );
137        }
138
139        // other recognized codes
140        switch ( result )
141        {
142        case 8         : kevent.key.code = nv::KEY_BACK; break;
143        case 9         : kevent.key.code = nv::KEY_TAB; break;
144        case 13        : kevent.key.code = nv::KEY_ENTER; break;
145        case 27        : kevent.key.code = nv::KEY_ESCAPE; break;
146        case 0x103     : kevent.key.code = nv::KEY_UP; break;
147        case 0x102     : kevent.key.code = nv::KEY_DOWN; break;
148        case 0x104     : kevent.key.code = nv::KEY_LEFT; break;
149        case 0x105     : kevent.key.code = nv::KEY_RIGHT; break;
150        case 0x153     : kevent.key.code = nv::KEY_PGUP; break;
151        case 0x152     : kevent.key.code = nv::KEY_PGDOWN; break;
152        case 0x106     : kevent.key.code = nv::KEY_HOME; break;
153        case 0x166     : kevent.key.code = nv::KEY_END; break;
154        }
155
156        // If key was understood by nv, then it's valid, otherwise ignored
157        return kevent.key.ascii != 0 || kevent.key.code != 0;
158}
159
160void curses_terminal::set_cursor( position p )
161{
162        terminal::set_cursor( p );
163        ::move( m_cursor.y-1, m_cursor.x-1 );
164}
165
166void curses_terminal::show_cursor()
167{
168        curs_set(1);
169}
170
171void curses_terminal::hide_cursor()
172{
173        curs_set(0);
174}
175
176curses_terminal::~curses_terminal()
177{
178        endwin();
179}
Note: See TracBrowser for help on using the repository browser.