commit
1a6e226dc1
|
@ -173,6 +173,7 @@ bool print_trackers = false;
|
||||||
bool print_peers = false;
|
bool print_peers = false;
|
||||||
bool print_log = false;
|
bool print_log = false;
|
||||||
bool print_downloads = false;
|
bool print_downloads = false;
|
||||||
|
bool print_matrix = false;
|
||||||
bool print_file_progress = false;
|
bool print_file_progress = false;
|
||||||
bool show_pad_files = false;
|
bool show_pad_files = false;
|
||||||
bool show_dht_status = false;
|
bool show_dht_status = false;
|
||||||
|
@ -377,9 +378,10 @@ FILE* g_log_file = 0;
|
||||||
std::string const& piece_bar(libtorrent::bitfield const& p, int width)
|
std::string const& piece_bar(libtorrent::bitfield const& p, int width)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
int const table_size = 2;
|
int const table_size = 5;
|
||||||
#else
|
#else
|
||||||
int const table_size = 18;
|
int const table_size = 18;
|
||||||
|
width *= 2; // we only print one character for every two "slots"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
double const piece_per_char = p.size() / double(width);
|
double const piece_per_char = p.size() / double(width);
|
||||||
|
@ -396,6 +398,10 @@ std::string const& piece_bar(libtorrent::bitfield const& p, int width)
|
||||||
|
|
||||||
// the [piece, piece + pieces_per_char) range is the pieces that are represented by each character
|
// the [piece, piece + pieces_per_char) range is the pieces that are represented by each character
|
||||||
double piece = 0;
|
double piece = 0;
|
||||||
|
|
||||||
|
// we print two blocks at a time, so calculate the color in pair
|
||||||
|
int color[2];
|
||||||
|
int last_color[2] = { -1, -1};
|
||||||
for (int i = 0; i < width; ++i, piece += piece_per_char)
|
for (int i = 0; i < width; ++i, piece += piece_per_char)
|
||||||
{
|
{
|
||||||
int num_pieces = 0;
|
int num_pieces = 0;
|
||||||
|
@ -403,15 +409,31 @@ std::string const& piece_bar(libtorrent::bitfield const& p, int width)
|
||||||
int end = (std::max)(int(piece + piece_per_char), int(piece) + 1);
|
int end = (std::max)(int(piece + piece_per_char), int(piece) + 1);
|
||||||
for (int k = int(piece); k < end; ++k, ++num_pieces)
|
for (int k = int(piece); k < end; ++k, ++num_pieces)
|
||||||
if (p[k]) ++num_have;
|
if (p[k]) ++num_have;
|
||||||
int color = int(std::ceil(num_have / float((std::max)(num_pieces, 1)) * (table_size - 1)));
|
int const c = int(std::ceil(num_have / float((std::max)(num_pieces, 1)) * (table_size - 1)));
|
||||||
char buf[40];
|
char buf[40];
|
||||||
#ifdef _WIN32
|
color[i & 1] = c;
|
||||||
snprintf(buf, sizeof(buf), "\x1b[4%dm", color ? 7 : 0);
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
if ((i & 1) == 1)
|
||||||
|
{
|
||||||
|
// now, print color[0] and [1]
|
||||||
|
// bg determines whether we're settings foreground or background color
|
||||||
|
static int const bg[] = { 38, 48};
|
||||||
|
for (int i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
if (color[i] != last_color[i])
|
||||||
|
{
|
||||||
|
snprintf(buf, sizeof(buf), "\x1b[%d;5;%dm", bg[i & 1], 232 + color[i]);
|
||||||
|
last_color[i] = color[i];
|
||||||
|
bar += buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bar += "\u258C";
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
snprintf(buf, sizeof(buf), "\x1b[48;5;%dm", 232 + color);
|
static char const table[] = {' ', '\xb0', '\xb1', '\xb2', '\xdb'};
|
||||||
|
bar += table[c];
|
||||||
#endif
|
#endif
|
||||||
bar += buf;
|
|
||||||
bar += " ";
|
|
||||||
}
|
}
|
||||||
bar += esc("0");
|
bar += esc("0");
|
||||||
bar += "]";
|
bar += "]";
|
||||||
|
@ -1913,6 +1935,7 @@ int main(int argc, char* argv[])
|
||||||
if (c == 'i') print_peers = !print_peers;
|
if (c == 'i') print_peers = !print_peers;
|
||||||
if (c == 'l') print_log = !print_log;
|
if (c == 'l') print_log = !print_log;
|
||||||
if (c == 'd') print_downloads = !print_downloads;
|
if (c == 'd') print_downloads = !print_downloads;
|
||||||
|
if (c == 'y') print_matrix = !print_matrix;
|
||||||
if (c == 'f') print_file_progress = !print_file_progress;
|
if (c == 'f') print_file_progress = !print_file_progress;
|
||||||
if (c == 'P') show_pad_files = !show_pad_files;
|
if (c == 'P') show_pad_files = !show_pad_files;
|
||||||
if (c == 'g') show_dht_status = !show_dht_status;
|
if (c == 'g') show_dht_status = !show_dht_status;
|
||||||
|
@ -1956,8 +1979,8 @@ int main(int argc, char* argv[])
|
||||||
"[i] toggle show peers [d] toggle show downloading pieces\n"
|
"[i] toggle show peers [d] toggle show downloading pieces\n"
|
||||||
"[u] show uTP stats [f] toggle show files\n"
|
"[u] show uTP stats [f] toggle show files\n"
|
||||||
"[g] show DHT [x] toggle disk cache stats\n"
|
"[g] show DHT [x] toggle disk cache stats\n"
|
||||||
"[t] show trackers [l] show alert log\n"
|
"[t] show trackers [l] toggle show log\n"
|
||||||
"[P] show pad files (in file list)\n"
|
"[P] show pad files (in file list) [y] toggle show piece matrix\n"
|
||||||
"\n"
|
"\n"
|
||||||
"COLUMN OPTIONS\n"
|
"COLUMN OPTIONS\n"
|
||||||
"[1] toggle IP column [2]\n"
|
"[1] toggle IP column [2]\n"
|
||||||
|
@ -2096,6 +2119,13 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (print_matrix)
|
||||||
|
{
|
||||||
|
int height = 0;
|
||||||
|
print(piece_matrix(s.pieces, terminal_width, &height).c_str());
|
||||||
|
pos += height;
|
||||||
|
}
|
||||||
|
|
||||||
if (print_downloads)
|
if (print_downloads)
|
||||||
{
|
{
|
||||||
h.get_download_queue(queue);
|
h.get_download_queue(queue);
|
||||||
|
|
|
@ -128,6 +128,101 @@ std::string const& progress_bar(int progress, int width, color_code c
|
||||||
return bar;
|
return bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_piece(libtorrent::bitfield const& p, int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= p.size()) return false;
|
||||||
|
return p.get_bit(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// this function uses the block characters that splits up the glyph in 4
|
||||||
|
// segments and provide all combinations of a segment lit or not. This allows us
|
||||||
|
// to print 4 pieces per character.
|
||||||
|
std::string piece_matrix(libtorrent::bitfield const& p, int width, int* height)
|
||||||
|
{
|
||||||
|
// print two rows of pieces at a time
|
||||||
|
int piece = 0;
|
||||||
|
++*height;
|
||||||
|
std::string ret;
|
||||||
|
ret.reserve((p.size() + width * 2 - 1) / width / 2 * 4);
|
||||||
|
while (piece < p.size())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < width; ++i)
|
||||||
|
{
|
||||||
|
// each character has 4 pieces. store them in a byte to use for lookups
|
||||||
|
int const c = get_piece(p, piece)
|
||||||
|
| (get_piece(p, piece+1) << 1)
|
||||||
|
| (get_piece(p, width*2+piece) << 2)
|
||||||
|
| (get_piece(p, width*2+piece+1) << 3);
|
||||||
|
|
||||||
|
// we have 4 bits, 16 different combinations
|
||||||
|
static char const* const chars[] =
|
||||||
|
{
|
||||||
|
" ", // no bit is set 0000
|
||||||
|
"\u2598", // upper left 0001
|
||||||
|
"\u259d", // upper right 0010
|
||||||
|
"\u2580", // both top bits 0011
|
||||||
|
"\u2596", // lower left 0100
|
||||||
|
"\u258c", // both left bits 0101
|
||||||
|
"\u259e", // upper right, lower left 0110
|
||||||
|
"\u259b", // left and upper sides 0111
|
||||||
|
"\u2597", // lower right 1000
|
||||||
|
"\u259a", // lower right, upper left 1001
|
||||||
|
"\u2590", // right side 1010
|
||||||
|
"\u259c", // lower right, top side 1011
|
||||||
|
"\u2584", // both lower bits 1100
|
||||||
|
"\u2599", // both lower, top left 1101
|
||||||
|
"\u259f", // both lower, top right 1110
|
||||||
|
"\x1b[7m \x1b[27m" // all bits are set (full block)
|
||||||
|
};
|
||||||
|
|
||||||
|
ret += chars[c];
|
||||||
|
piece += 2;
|
||||||
|
}
|
||||||
|
ret += '\n';
|
||||||
|
++*height;
|
||||||
|
piece += width * 2; // skip another row, as we've already printed it
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// on MS-DOS terminals, we only have block characters for upper half and lower
|
||||||
|
// half. This lets us print two pieces per character.
|
||||||
|
std::string piece_matrix(libtorrent::bitfield const& p, int width, int* height)
|
||||||
|
{
|
||||||
|
// print two rows of pieces at a time
|
||||||
|
int piece = 0;
|
||||||
|
++*height;
|
||||||
|
std::string ret;
|
||||||
|
ret.reserve((p.size() + width * 2 - 1) / width);
|
||||||
|
while (piece < p.size())
|
||||||
|
{
|
||||||
|
for (int i = 0; i < width; ++i)
|
||||||
|
{
|
||||||
|
// each character has 8 pieces. store them in a byte to use for lookups
|
||||||
|
// the ordering of these bits
|
||||||
|
int const c = get_piece(p, piece)
|
||||||
|
| (get_piece(p, width*2+piece) << 1);
|
||||||
|
|
||||||
|
static char const* const chars[] =
|
||||||
|
{
|
||||||
|
" ", // no piece 00
|
||||||
|
"\xdf", // top piece 01
|
||||||
|
"\xdc", // bottom piece 10
|
||||||
|
"\xdb" // both pieces 11
|
||||||
|
};
|
||||||
|
|
||||||
|
ret += chars[c];
|
||||||
|
++piece;
|
||||||
|
}
|
||||||
|
ret += '\n';
|
||||||
|
++*height;
|
||||||
|
piece += width * 2; // skip another row, as we've already printed it
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void set_cursor_pos(int x, int y)
|
void set_cursor_pos(int x, int y)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define PRINT_HPP_
|
#define PRINT_HPP_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "libtorrent/bitfield.hpp"
|
||||||
|
|
||||||
enum color_code
|
enum color_code
|
||||||
{
|
{
|
||||||
|
@ -36,6 +37,7 @@ void clear_screen();
|
||||||
void clear_rows(int y1, int y2);
|
void clear_rows(int y1, int y2);
|
||||||
|
|
||||||
void terminal_size(int* terminal_width, int* terminal_height);
|
void terminal_size(int* terminal_width, int* terminal_height);
|
||||||
|
std::string piece_matrix(libtorrent::bitfield const& p, int width, int* height);
|
||||||
|
|
||||||
void print(char const* str);
|
void print(char const* str);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue