File Coverage

blib/lib/Games/Roguelike/Console/Curses.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1 5     5   25 use strict;
  5         11  
  5         232  
2             package Games::Roguelike::Console::Curses;
3 5     5   2072 use Curses qw(noecho cbreak curs_set start_color);
  0            
  0            
4             use base qw(Curses::Window Games::Roguelike::Console);
5             use Carp qw(croak cluck);
6             use POSIX;
7             use warnings::register;
8            
9             our $VERSION = '0.4.' . [qw$Revision: 233 $]->[1];
10            
11             my $ATTR = 0;
12            
13             sub new {
14             my $pkg = shift;
15             croak "usage: Games::Roguelike::Console::Curses->new()" unless $pkg;
16            
17             my $r = new Curses qw();
18             bless $r, $pkg;
19             $r->init(@_);
20             return $r;
21             }
22            
23             my %COLORS;
24            
25             my $KEY_LEFT = Curses::KEY_LEFT;
26             my $KEY_RIGHT = Curses::KEY_RIGHT;
27             my $KEY_DOWN = Curses::KEY_DOWN;
28             my $KEY_UP = Curses::KEY_UP;
29             my $KEY_DELETE = Curses::KEY_DC;
30             my $KEY_BACKSPACE = Curses::KEY_BACKSPACE;
31             my %CONDATA;
32            
33             sub init {
34             my $self = shift;
35             my %opts = @_;
36             if (!$opts{noinit}) {
37             $self->keypad(1);
38             $self->color_init();
39             $self->SUPER::init(%opts);
40             curs_set(0);
41             noecho();
42             cbreak();
43             $SIG{INT} = \&sig_int_handler; # endwin b4 die text comes out
44             $SIG{__DIE__} = \&sig_die_handler; # endwin b4 die text comes out
45             }
46             }
47            
48             sub color_init {
49             no strict 'refs';
50             start_color();
51             my $i = 0;
52             for my $fg (qw(white blue cyan green yellow magenta black red)) {
53             for my $bg (qw(black white blue cyan green yellow magenta red)) {
54             $COLORS{$fg}{$bg} = ++$i;
55             Curses::init_pair($COLORS{$fg}{$bg},&{"Curses::COLOR_".uc($fg)}, &{"Curses::COLOR_".uc($bg)});
56             }}
57             use strict 'refs';
58             }
59            
60             sub sig_die_handler {
61             die @_ if $^S;
62             Curses::endwin();
63             die @_;
64             }
65            
66             sub sig_int_handler {
67             Curses::endwin();
68             exit;
69             }
70            
71             sub DESTROY {
72             Curses::endwin();
73             if ($^O =~ /linux|darwin/) {
74             if (my $tty = POSIX::ttyname(1)) {
75             system("stty -F $tty sane");
76             }
77             }
78             }
79            
80             sub nativecolor {
81             my ($self, $fg, $bg, $bold) = @_;
82             if (warnings::enabled() && !$COLORS{$fg}{$bg}) {
83             cluck("Uninitialized color pair ($fg-$bg)");
84             }
85             return Curses::COLOR_PAIR($COLORS{$fg}{$bg}) | ($bold ? Curses::A_BOLD : 0);
86             }
87            
88             sub tagstr {
89             my $self = shift;
90            
91             my ($y, $x, $str);
92            
93             if (@_ >= 3) {
94             ($y, $x, $str) = @_;
95             $self->move($y, $x);
96             } elsif (@_ == 1) {
97             ($str) = @_;
98             }
99            
100             return if !defined($str);
101            
102             my $hasattr;
103             my $c;
104             for (my $i = 0; $i < length($str); ++$i) {
105             $c = substr($str,$i,1);
106             if ($c eq '<') {
107             substr($str,$i) =~ s/^<([^>]*)>//;
108             if ($1 eq 'gt') {
109             $c = '>';
110             --$i;
111             } elsif ($1 eq 'lt') {
112             $c = '<';
113             --$i;
114             } else {
115             if ($1) {
116             $self->attron($1);
117             $hasattr = 1;
118             } else {
119             $self->attroff();
120             }
121             $c = substr($str,$i,1);
122             }
123             }
124             $self->addch($c);
125             }
126             $self->attroff() if $hasattr;
127             }
128            
129             sub attron {
130             my $self = shift;
131             my ($attr) = lc(shift);
132             if ($ATTR) {
133             $self->SUPER::attroff($ATTR);
134             }
135             $ATTR = $self->parsecolor($attr);
136             $self->SUPER::attron($ATTR);
137             }
138            
139             sub attroff {
140             my $self = shift;
141             $self->SUPER::attroff($ATTR);
142             $ATTR = 0;
143             }
144            
145             sub getch {
146             my $self = shift;
147             my $c =$self->SUPER::getch();
148             if ($c eq $KEY_UP) {
149             return 'UP';
150             } elsif ($c eq $KEY_DOWN) {
151             return 'DOWN';
152             } elsif ($c eq $KEY_LEFT) {
153             return 'LEFT';
154             } elsif ($c eq $KEY_RIGHT) {
155             return 'RIGHT';
156             } elsif ($c eq $KEY_DELETE) {
157             return 'DELETE';
158             } elsif ($c eq $KEY_BACKSPACE) {
159             return 'BACKSPACE';
160             } elsif (ord($c) == 27) {
161             return 'ESC';
162             }
163             return $c;
164             }
165            
166             sub nbgetch {
167             my $self = shift;
168             $self->nodelay(1);
169             my $c =$self->getch();
170             $self->nodelay(0);
171             return $c;
172             }
173            
174             sub cursor {
175             my $self = shift;
176             curs_set($_[0])
177             }
178            
179             sub redraw {
180             my $self=shift;
181             $self->redrawwin();
182             }
183            
184             1;