use
Carp
qw(cluck confess)
;
BEGIN {
}
@Games::Rezrov::ZIO_Curses::ISA
=
qw(
Games::Rezrov::ZIO_Generic
Games::Rezrov::ZIO_Color
)
;
need_endwin
rows
columns
color_pairs
zfont
)
;
my
$w_main
;
my
%COLORMAP
= (
black
=> COLOR_BLACK,
red
=> COLOR_RED,
green
=> COLOR_GREEN,
yellow
=> COLOR_YELLOW,
blue
=> COLOR_BLUE,
magenta
=> COLOR_MAGENTA,
cyan
=> COLOR_CYAN,
white
=> COLOR_WHITE);
my
$color_pair_counter
= 0;
sub
new {
my
(
$type
,
%options
) =
@_
;
my
$self
= new Games::Rezrov::ZIO_Generic(
%options
);
bless
$self
,
$type
;
$self
->zio_options(\
%options
);
$self
->readline_init();
initscr() ||
die
;
$self
->need_endwin(1);
my
$columns
=
$options
{
"columns"
} ||
$Curses::COLS
||
die
"need columns!"
;
my
$rows
=
$options
{
"rows"
} ||
$Curses::LINES
||
die
"need rows!"
;
$self
->rows(
$rows
);
$self
->columns(
$columns
);
$w_main
= newwin(
$rows
,
$columns
, 0, 0);
$w_main
->keypad(1);
$self
->color_pairs({});
$self
->parse_color_options(\
%options
);
$self
->init_colors(\
%options
);
$self
->zfont(Games::Rezrov::ZConst::FONT_NORMAL);
return
$self
;
}
sub
groks_font_3 {
return
1;
}
sub
can_use_color {
return
has_colors() ? 1 : 0;
}
sub
update {
$w_main
->refresh();
}
sub
set_version {
my
(
$self
,
$status_needed
,
$callback
) =
@_
;
Games::Rezrov::StoryFile::rows(
$self
->rows);
Games::Rezrov::StoryFile::columns(
$self
->columns);
$self
->clear_screen();
scrollok(
$w_main
, 1);
noecho();
return
0;
}
sub
set_background_color {
if
(has_colors() and
$_
[0]->fg() and
$_
[0]->bg()) {
$_
[0]->do_colors(
$_
[0]->fg(),
$_
[0]->bg());
}
}
sub
clear_screen {
$w_main
->erase();
}
sub
get_position {
my
(
$self
,
$sub
) =
@_
;
my
(
$x
,
$y
);
$w_main
->getyx(
$y
,
$x
);
if
(
$sub
) {
return
sub
{
$w_main
->move(
$y
,
$x
); };
}
else
{
return
(
$x
,
$y
);
}
}
sub
newline {
$w_main
->addstr(
"\n"
);
Games::Rezrov::StoryFile::register_newline();
update()
if
Games::Rezrov::ZOptions::MAXIMUM_SCROLLING;
}
sub
write_zchar {
if
(
$_
[0]->zfont() == 3) {
if
(
$_
[1] == 32 ||
$_
[1] == 37) {
$w_main
->addch(
" "
);
}
elsif
(
$_
[1] == 35 ||
$_
[1] == 50 ||
$_
[1] == 52 ||
$_
[1] == 67 ||
$_
[1] == 69) {
$w_main
->addch(
"/"
);
}
elsif
(
$_
[1] == 36 ||
$_
[1] == 51 ||
$_
[1] == 53 ||
$_
[1] == 68 ||
$_
[1] == 70) {
$w_main
->addch(
'\\'
);
}
elsif
(
$_
[1] == 46) {
$w_main
->addch(ACS_LLCORNER);
}
elsif
(
$_
[1] == 47) {
$w_main
->addch(ACS_ULCORNER);
}
elsif
(
$_
[1] == 48) {
$w_main
->addch(ACS_URCORNER);
}
elsif
(
$_
[1] == 49) {
$w_main
->addch(ACS_LRCORNER);
}
elsif
(
$_
[1] == 42) {
$w_main
->addch(ACS_BTEE);
}
elsif
(
$_
[1] == 43) {
$w_main
->addch(ACS_TTEE);
}
elsif
(
$_
[1] == 44) {
$w_main
->addch(ACS_LTEE);
}
elsif
(
$_
[1] == 45) {
$w_main
->addch(ACS_RTEE);
}
elsif
(
$_
[1] == 54) {
$w_main
->addch(ACS_BLOCK);
}
elsif
(
$_
[1] == 38 ||
$_
[1] == 39 ||
$_
[1] == 61 ||
$_
[1] == 62) {
$w_main
->addch(ACS_HLINE);
}
elsif
(
$_
[1] == 40 ||
$_
[1] == 41 ||
$_
[1] == 59 ||
$_
[1] == 60) {
$w_main
->addch(ACS_VLINE);
}
elsif
(
$_
[1] == 90) {
$w_main
->addch(
"X"
);
}
elsif
(
$_
[1] == 96) {
$w_main
->addch(
"?"
);
}
else
{
$w_main
->addch(ACS_BULLET);
}
}
else
{
$w_main
->addch(
chr
(
$_
[1]));
}
}
sub
status_hook {
my
(
$self
,
$type
) =
@_
;
if
(
$type
== 0) {
if
(has_colors()) {
$w_main
->bkgd(0);
$self
->do_colors(
$self
->sfg(),
$self
->sbg());
}
else
{
$w_main
->attrset(A_REVERSE);
}
}
else
{
if
(has_colors()) {
$self
->do_colors(
$self
->fg(),
$self
->bg());
}
else
{
$w_main
->attrset(A_NORMAL);
}
}
}
sub
write_string {
my
(
$self
,
$string
,
$x
,
$y
) =
@_
;
$self
->absolute_move(
$x
,
$y
)
if
defined
(
$x
) and
defined
(
$y
);
$w_main
->addstr(
$string
);
}
sub
get_input {
my
(
$self
,
$max
,
$single_char
,
%options
) =
@_
;
my
$result
;
echo();
if
(
$single_char
) {
$result
= get_char();
}
else
{
my
(
$x
,
$y
) =
$self
->get_position();
scrollok(
$w_main
, 0);
if
(
$self
->using_term_readline()) {
$result
=
$self
->
readline
(
$options
{
"-preloaded"
});
}
else
{
$result
=
""
;
if
(
$options
{
"-preloaded"
}) {
$result
=
$options
{
"-preloaded"
};
$x
-=
length
$result
;
}
my
(
$char
,
$ord
);
noecho();
cbreak();
while
(1) {
$char
=
$w_main
->getch();
$ord
=
ord
(
$char
);
if
(
$char
eq KEY_BACKSPACE or
$ord
== Games::Rezrov::ZConst::ASCII_DEL or
$ord
== Games::Rezrov::ZConst::ASCII_BS
) {
my
$len
=
length
$result
;
if
(
$len
) {
$result
=
substr
(
$result
, 0, --
$len
);
$w_main
->move(
$y
,
$x
+
$len
);
$w_main
->addch(
" "
);
$w_main
->move(
$y
,
$x
+
$len
);
}
}
elsif
(
$ord
== Games::Rezrov::ZConst::ASCII_LF or
$ord
== Games::Rezrov::ZConst::ASCII_CR) {
last
;
}
elsif
(
length
$result
<
$max
) {
$result
.=
$char
;
$w_main
->addch(
$char
);
$w_main
->touchline(
$y
, 1);
}
}
nocbreak();
}
scrollok(
$w_main
, 1);
$w_main
->move(
$y
,
$x
+
length
(
$result
));
$self
->newline();
}
noecho();
return
$result
;
}
sub
get_char {
my
$char
;
noecho();
cbreak();
$char
=
$w_main
->getch();
nocbreak();
echo();
if
(
$char
=~ /^\d+$/) {
if
(
$char
== KEY_UP) {
$char
=
chr
(Games::Rezrov::ZConst::Z_UP);
}
elsif
(
$char
== KEY_DOWN) {
$char
=
chr
(Games::Rezrov::ZConst::Z_DOWN);
}
elsif
(
$char
== KEY_LEFT) {
$char
=
chr
(Games::Rezrov::ZConst::Z_LEFT);
}
elsif
(
$char
== KEY_RIGHT) {
$char
=
chr
(Games::Rezrov::ZConst::Z_RIGHT);
}
}
return
$char
;
}
sub
clear_to_eol {
$w_main
->clrtoeol();
}
sub
split_window {
my
(
$self
,
$lines
) =
@_
;
$w_main
->setscrreg(
$lines
,
$self
->rows() - 1);
}
sub
set_text_style {
my
(
$self
,
$text_style
) =
@_
;
if
(
$text_style
== Games::Rezrov::ZConst::STYLE_ROMAN) {
$w_main
->attrset(A_NORMAL);
}
else
{
my
$mask
= 0;
$mask
|= A_REVERSE
if
(
$text_style
& Games::Rezrov::ZConst::STYLE_REVERSE);
$mask
|= A_BOLD
if
(
$text_style
& Games::Rezrov::ZConst::STYLE_BOLD);
$mask
|= A_UNDERLINE
if
(
$text_style
& Games::Rezrov::ZConst::STYLE_ITALIC);
$w_main
->attrset(
$mask
);
}
}
sub
cleanup {
if
(
$_
[0]->need_endwin()) {
endwin();
$_
[0]->need_endwin(0);
}
}
sub
absolute_move {
$w_main
->move(
$_
[2],
$_
[1]);
}
sub
init_colors {
my
(
$self
,
$options
) =
@_
;
if
(has_colors()) {
foreach
(
map
{
$self
->
$_
()}
qw (fg
bg sfg sbg)) {
if
(
$_
and !
exists
$COLORMAP
{
$_
}) {
$self
->fatal_error(
sprintf
"Unknown color \"%s\"; available colors are %s.\n"
,
$_
,
join
", "
,
sort
keys
%COLORMAP
);
}
}
start_color();
$self
->do_colors(
$self
->fg(),
$self
->bg());
}
elsif
(
$options
->{fg} or
$options
->{bg} or
$options
->{sfg} or
$options
->{sbg}) {
my
$message
=
"You specified colors, but your terminal does not seem to\nsupport color. Is your TERM variable set correctly?\n"
;
if
($^O =~ /linux/i) {
$message
.=
"You seem to be using Linux; if you are using color_xterm,\nhave you tried setting TERM to \"xterm-color\"?"
;
}
$self
->fatal_error(
$message
);
}
}
sub
color_change_notify {
$_
[0]->do_colors(
$_
[0]->fg(),
$_
[0]->bg());
}
sub
do_colors {
my
(
$self
,
$fg
,
$bg
) =
@_
;
if
(has_colors()) {
my
$color_pairs
=
$self
->color_pairs();
my
$key
=
$fg
.
","
.
$bg
;
my
$pair
;
if
(
exists
$color_pairs
->{
$key
}) {
$pair
=
$color_pairs
->{
$key
};
}
else
{
$pair
= ++
$color_pair_counter
;
init_pair(
$pair
,
$COLORMAP
{
$fg
},
$COLORMAP
{
$bg
});
$color_pairs
->{
$key
} =
$pair
;
}
$w_main
->bkgdset(COLOR_PAIR(
$pair
));
}
}
sub
set_font {
return
$_
[0]->zfont(
$_
[1]);
}
1;