Language-Zcode
view release on metacpan or search on metacpan
lib/Language/Zcode/Runtime/IO.pm view on Meta::CPAN
if ($t eq "dumb") {
$zio = new Games::Rezrov::ZIO_dumb(rows=>$r, columns =>$c);
} elsif ($t eq "win32") {
$zio = new Games::Rezrov::ZIO_Win32(rows=>$r, columns =>$c);
} else {
die "Unknown terminal '$t'\n";
}
$zio->set_window(Games::Rezrov::ZConst::LOWER_WIN);
PlotzPerl::Output::start_output($zio);
# erase_window call in setup_IO calls clear_screen
# $zio->clear_screen();
}
# Call again for restart
sub setup_IO {
# XXX I don't handle undo yet ADK
# $undo_slots = [];
# cursor positions for individual windows
$window_cursors = [];
PlotzPerl::Output::setup();
Language::Zcode::Runtime::Input::setup();
# HACKS, FIX ME
# $zio->set_version($self);
# collapses the upper window
# XXX do we really want to clear screen on a restart?
erase_window(-1);
# Centralized management of the status line.
# Perform a split_window(), we'll use the "upper window"
# for the status line.
# This is BROKEN: Seastalker is a v3 game that uses the upper window!
=pod
# So [ADK] split to a SECOND window. This split will be internal to
# the Z-machine emulator: the Z-machine isn't able to split to more
# than one window (in v5), but presumably any I/O that can split once
# can split more than once. Put status in that window.
#
# Tk already does that. Just use manual_status_line for
# everything.
=cut
if ($main::Constants{version} <= 3 &&
$zio->can_split() &&
!$zio->manual_status_line()) {
split_window(1);
}
# XXX ADK I think we don't need the $current_window line below - that
# is taken care of by set_window
# $current_window = Games::Rezrov::ZConst::LOWER_WIN;
set_window(Games::Rezrov::ZConst::LOWER_WIN);
}
# Read IO stuff from header, write some back depending on interpreter/IO
sub update_header {
my $version = $main::Constants{version};
# First do flags1 stuff
# a "time" game: 8.2.3.2
#my $f1 = PlotzMemory::get_byte_at(FLAGS_1);
my $f1 = $PlotzMemory::Memory[FLAGS_1];
my $start_rows = rows();
my $start_columns = columns();
# $f1 |= TANDY if Games::Rezrov::ZOptions::TANDY_BIT();
# turn on the "tandy bit"
if ($version <= 3) {
if ($zio->can_split()) {
$f1 |= SCREEN_SPLITTING_AVAILABLE;
$f1 &= ~ STATUS_NOT_AVAILABLE;
} else {
$f1 &= ~ SCREEN_SPLITTING_AVAILABLE;
$f1 |= STATUS_NOT_AVAILABLE;
}
# XXX copied from Games::Rezrov::ZHeader. Isn't this backwards?!
if ($zio->fixed_font_default()) {
$f1 |= VARIABLE_FONT_DEFAULT;
} else {
$f1 &= ~VARIABLE_FONT_DEFAULT;
}
# versions 4+
} else {
# Are they always available? Even for dumb term?
$f1 |= BOLDFACE_AVAILABLE;
$f1 |= ITALIC_AVAILABLE;
$f1 |= FIXED_FONT_AVAILABLE;
# $f1 |= 0x80;
$f1 &= ~TIMED_INPUT_AVAILABLE; # timed input NOT available
set_header_columns($start_columns);
set_header_rows($start_rows);
if ($version >= 5) {
if ($zio->can_use_color()) {
$f1 |= COLOURS_AVAILABLE;
}
}
}
# write back flag1
PlotzMemory::set_byte_at(FLAGS_1, $f1);
# Now do flags2 stuff
if ($version >= 5) {
# 8.3.3: default foreground and background
# FIX ME!
my $f2 = PlotzMemory::get_word_at(FLAGS_2);
# if ($zio->groks_font_3() and
# !Games::Rezrov::StoryFile::font_3_disabled()) {
# ZIO can decode font 3 characters
# $f2 |= WANTS_PICTURES;
lib/Language/Zcode/Runtime/IO.pm view on Meta::CPAN
$self->io_setup($options{"readline"});
($columns, $rows) = Games::Rezrov::GetSize::get_size();
$columns = $options{columns} if $options{columns};
$rows = $options{rows} if $options{rows};
unless ($columns and $rows) {
#print "I couldn't guess the number of rows and columns in your display,\n";
#print "so you must use -r and -c to specify them manually.\n";
#exit;
# XXX HACK!
$columns = 80; $rows = 250;
}
Language::Zcode::Runtime::IO::rows($rows);
Language::Zcode::Runtime::IO::columns($columns);
return $self;
}
sub io_setup {
my ($self, $readline_ok) = @_;
if (eval('require Term::ReadKey')) {
import Term::ReadKey;
$have_term_readkey = 1;
# ReadMode(3);
# disable echoing
# ReadLine(-1);
# make sure we don't buffer any (invisible) characters
}
if ($readline_ok && eval('require Term::ReadLine')) {
require Term::ReadLine;
$have_term_readline = 1;
$tr = new Term::ReadLine 'what?', \*main::STDIN, \*main::STDOUT;
$tr->ornaments(0);
}
# TODO if $^O == windows, "cls". If unix, `which clear`
$clear_prog = undef; # find_prog("clear");
}
sub write_string {
my ($self, $string, $x, $y) = @_;
$self->absolute_move($x, $y) if defined($x) && defined($y);
print $string;
# print STDERR "ws: $string\n";
$abs_x += length($string);
}
sub clear_to_eol {
# print STDERR "clear to eol; at $abs_x\n";
my $diff = $columns - $abs_x;
if ($diff > 0) {
print " " x $diff;
# erase
print pack("c", 0x08) x $diff;
# restore cursor
}
}
sub update {
}
#sub find_prog {
# foreach ("/bin/", "/usr/bin/") {
# my $fn = $_ . $_[0];
# return $fn if -x $fn;
# }
# return undef;
#}
sub can_split {
# true or false: can this zio split the screen?
return 0;
}
sub set_version {
die "Not using set_version any more";
# my ($self, $status_needed, $callback) = @_;
# Games::Rezrov::StoryFile::rows($rows);
# Games::Rezrov::StoryFile::columns($columns);
# print STDERR "$columns\n";
# $self->clear_screen();
return 0;
}
sub absolute_move {
my ($nx, $ny) = @_[1,2];
# printf STDERR "move X to $nx from $abs_x\n";
if (0 and $nx < $abs_x) {
# DISABLED
# "this sidewalk's for regular walkin', not fancy walkin'..."
my $diff = $abs_x - $nx;
# printf STDERR "going back %d\n", $abs_x - $nx;
print pack("c", 0x08) x $diff;
# go back
print " " x $diff;
# erase
print pack("c", 0x08) x $diff;
# go back again
}
$abs_x = $nx;
$abs_y = $ny;
}
sub newline {
# check to see if we need to pause
print "\n";
$abs_x = 0;
PlotzPerl::Output::register_newline();
}
sub write_zchar {
if ($_[0]->current_window() == Games::Rezrov::ZConst::LOWER_WIN) {
print chr($_[1]);
# printf STDERR "wc: %s\n", chr($_[1]);
$abs_x++;
} else {
# printf STDERR "ignoring char: %s\n", chr($_[1]);
}
}
lib/Language/Zcode/Runtime/IO.pm view on Meta::CPAN
$FOREGROUND{$_} = ${"main::FG_" . uc($_)};
$BACKGROUND{$_} = ${"main::BG_" . uc($_)};
}
sub new {
my ($type, %options) = @_;
my $self = new Games::Rezrov::ZIO_Generic();
bless $self, $type;
if ($options{fg}) {
$options{fg} = "gray" if $options{fg} eq "white";
# since INTENSITY mode has no effect "white",
# use gray instead. Feh.
# How to get *true* bold here???
} else {
$options{fg} = "gray" unless $options{fg};
$options{bg} = "blue" unless $options{bg};
$options{sfg} = "black" unless $options{sfg};
$options{sbg} = "cyan" unless $options{sbg};
}
$self->parse_color_options(\%options);
foreach ("bg", "fg", "sfg", "sbg") {
next unless exists $options{$_};
my $c = $self->$_() || next;
die sprintf "Unknown color \"%s\"; available colors: %s\n", $c, join(", ", sort keys %FOREGROUND)
unless exists $FOREGROUND{$c};
}
# set up i/o
$IN = new Win32::Console(STD_INPUT_HANDLE);
$OUT = new Win32::Console(STD_OUTPUT_HANDLE);
my @size = $OUT->Size();
$s_columns = $options{"-columns"} || $size[0] || die "need columns!";
$s_rows = $options{"-rows"} || $size[1] || die "need rows!";
($orig_columns, $orig_rows) = @size;
###########
# ADK XXX I have no idea if this is right, but it shrinks the Windows
# buffer to be the same size as the screen, so that the status line
# on row zero is visible without scrolling upward!
# Seems like there should be a way to keep the scrollbar and to
# allow the lower window to scroll up, always rewriting the upper
# window. But maybe Win32::Console doesn't play nice with that.
my @w = $OUT->Window();
my ($c, $r) = ($w[2]-$w[0]+1, $w[3]-$w[1]+1);
# $OUT->Write($size[0]." "); $OUT->Write($size[1]." "); $OUT->Write("$r $c");
$OUT->Size($c, $r);
$s_columns = $options{"-columns"} || $c || die "need columns!";
$s_rows = $options{"-rows"} || $r || die "need rows!";
###########
Language::Zcode::Runtime::IO::rows($s_rows);
Language::Zcode::Runtime::IO::columns($s_columns);
$s_upper_lines = 0;
return $self;
}
sub update {
$OUT->Flush();
}
sub set_version {
# called by the game
my ($self, $status_needed, $callback) = @_;
Games::Rezrov::StoryFile::rows($s_rows);
Games::Rezrov::StoryFile::columns($s_columns);
return 0;
}
sub absolute_move {
# move to X, Y
$OUT->Cursor($_[1], $_[2]);
}
sub write_string {
my ($self, $string, $x, $y) = @_;
$self->absolute_move($x, $y) if defined($x) and defined($y);
# $OUT->Attr($current_attr);
$OUT->Attr($self->get_attr());
$OUT->Write($string);
}
sub newline {
# newline/scroll
my ($x, $y) = $OUT->Cursor();
if (++$y >= $s_rows) {
# scroll needed
my $last_line = $s_rows - 1;
$y = $last_line;
my $top = $s_upper_lines;
# $OUT->Write(sprintf "before: at %d,%d, top=%d last=%d\n", $x, $y, $top, $last_line);
# log_it(sprintf "before: at %d,%d, top=%d last=%d\n", $x, $y, $top, $last_line);
# sleep(1);
$OUT->Scroll(0, $top + 1, $s_columns - 1, $last_line,
0, $top, Games::Rezrov::ZConst::ASCII_SPACE, $_[0]->get_attr(0),
0, $top, $s_columns - 1, $last_line);
# ugh: we have to specify the clipping region, or else
# Win32::Console barfs about uninitialized variables (with -w)
}
PlotzPerl::Output::register_newline();
$_[0]->absolute_move(0, $y);
}
sub write_zchar {
# log_it("wzchar: " . chr($_[1]));
$OUT->Attr($_[0]->get_attr());
$OUT->Write(chr($_[1]));
}
sub status_hook {
my ($self, $type) = @_;
# 0 = before
# 1 = after
if ($type == 0) {
# before printing status line
$OUT->Cursor(0,0);
$in_status = 1;
$OUT->FillAttr($self->get_attr(), $s_columns, 0, 0);
( run in 1.837 second using v1.01-cache-2.11-cpan-5b529ec07f3 )