From b792b0a8e7578ad85bc892fc0288caefa028e1b7 Mon Sep 17 00:00:00 2001 From: Peisong Xiao Date: Fri, 5 Jul 2024 19:31:09 -0400 Subject: [PATCH] fixed: all ready for input-testing --- src/console_output.cc | 97 +++++++++++++++++++++++++++++++++++++++++++ src/console_output.h | 22 ++++++++++ src/constants.h | 2 + src/display.cc | 21 +--------- src/display.h | 40 +++++++++--------- src/file_output.cc | 29 +++++++++++++ src/file_output.h | 21 ++++++++++ 7 files changed, 193 insertions(+), 39 deletions(-) create mode 100644 src/console_output.cc create mode 100644 src/console_output.h create mode 100644 src/file_output.cc create mode 100644 src/file_output.h diff --git a/src/console_output.cc b/src/console_output.cc new file mode 100644 index 0000000..c2d6846 --- /dev/null +++ b/src/console_output.cc @@ -0,0 +1,97 @@ +#include "console_output.h" + +#include +#include + + +console_output::console_output(std::ostream &new_out): out{new_out} {} + +/* Attributes + black 30 40 + red 31 41 + green 32 42 + yellow 33 43 + blue 34 44 + magenta 35 45 + cyan 36 46 + white 37 47 + reset 0 (everything back to normal) + bold/bright 1 (often a brighter shade of the same colour) + underline 4 + inverse 7 (swap foreground and background colours) + bold/bright off 21 + underline off 24 + inverse off 27 + + Format: + \033[X;Ym + X Y are numbers from above +*/ + +std::string console_output::get_code(const int attr) { + if (attr < 255) + return "\033[0m"; + + std::string result = "\033["; + + if (attr & A_STANDOUT) + result += "1;"; + + if (attr & A_UNDERLINE) + result += "4;"; + + if (attr & COLOR_PAIR(COLOR_BLACK)) + result += "30;"; + + if (attr & COLOR_PAIR(COLOR_RED)) + result += "31;"; + + if (attr & COLOR_PAIR(COLOR_GREEN)) + result += "32;"; + + if (attr & COLOR_PAIR(COLOR_YELLOW)) + result += "33;"; + + if (attr & COLOR_PAIR(COLOR_BLUE)) + result += "34;"; + + if (attr & COLOR_PAIR(COLOR_MAGENTA)) + result += "35;"; + + if (attr & COLOR_PAIR(COLOR_CYAN)) + result += "36;"; + + if (attr & COLOR_PAIR(COLOR_WHITE)) + result += "37;"; + + result[result.length() - 1] = 'm'; + return result; +} + +void console_output::render() { + for (std::size_t idx = 0; idx < contents.size(); ++idx) { + if (idx % DISPLAY_WIDTH == 0 && idx) + out << std::endl; + + out << get_code(contents[idx]) + (char)contents[idx]; + } +} + +void console_output::print_char(const position &pos, const char ch, + const int attr) { + if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT) + return; + + contents[pos.y * DISPLAY_WIDTH + pos.x] = attr | ch; +} + +void console_output::print_str(const position &pos, const std::string &str, + const int attr) { + if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT) + return; + + int head = pos.y * DISPLAY_WIDTH + pos.x; + + for (std::size_t i = 0; i < str.length(); ++i) + contents[i + head] = attr | str[i]; +} diff --git a/src/console_output.h b/src/console_output.h new file mode 100644 index 0000000..9610e17 --- /dev/null +++ b/src/console_output.h @@ -0,0 +1,22 @@ +#ifndef __CONSOLE_OUTPUT_H__ +#define __CONSOLE_OUTPUT_H__ + +#include +#include "display.h" + +class console_output final : public display { +private: + std::ostream &out; + std::string get_code(const int attr); +public: + console_output(std::ostream &new_out); + + void render() override; + void clear() override; + void print_char(const position &pos, + const char ch, const int attr) override; + void print_str(const position &pos, + const std::string &str, const int attr) override; +}; + +#endif diff --git a/src/constants.h b/src/constants.h index e21836c..0695388 100644 --- a/src/constants.h +++ b/src/constants.h @@ -60,6 +60,8 @@ const int MAP_HEIGHT = 25; const int MAP_WIDTH = 79; const int DISPLAY_HEIGHT = 30; const int DISPLAY_WIDTH = 79; +const int DISPLAY_BUFFER_SIZE = DISPLAY_HEIGHT * DISPLAY_WIDTH + + DISPLAY_WIDTH * 3; // TODO: list all extra features // using constants to keep track of features diff --git a/src/display.cc b/src/display.cc index 439ba35..c868fd4 100644 --- a/src/display.cc +++ b/src/display.cc @@ -1,21 +1,4 @@ #include "display.h" -display::display(): contents{DISPLAY_HEIGHT} {} - -void display::clear() { - for (auto line : contents) - line.clear(); -} - -void display::print(std::ostream &out) const { - for (auto line : contents) - out << line; -} - -void display::print_line(const std::string &line, const int linenum) { - contents[linenum] = line; -} - -void display::print_position(const position &pos, const char ch) { - contents[pos.y][pos.x] = ch; -} +display::display(): + contents{DISPLAY_BUFFER_SIZE, 0} {} diff --git a/src/display.h b/src/display.h index 03d0723..06bd63a 100644 --- a/src/display.h +++ b/src/display.h @@ -1,35 +1,35 @@ -/* - * CS 246 Final Project - * File: display.h - * Purpose: handles map functionality - */ - #ifndef __DISPLAY_H__ #define __DISPLAY_H__ -#include -#include + #include #include "position.h" #include "constants.h" #include "cursor.h" -class display final { -private: - std::vector contents; - cursor &curse; +class display { +protected: + // use an array of ints to keep track of what's on the screen + // This will have a bit of buffer for the last line + // just in case it overflows + std::vector contents; public: display(); - display(cursor &new_curse, int argc, char **argv); - void clear(); - // use this instead of overloading for clarity - void print(std::ostream &out) const; - void print_line(const std::string &line, const int linenum); + virtual ~display() = default; - void render() const ; + // Only call this to refresh the entire output + virtual void render() = 0; - // will override any character that was there - void print_position(const position &pos, const char ch); + // Clears the contents buffer + virtual void clear() = 0; + + virtual void print_char(const position &pos, const char ch, + const int attr = + A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0; + virtual void print_str(const position &pos, const std::string &str, + const int attr = + A_NORMAL | COLOR_PAIR(COLOR_WHITE)) = 0; + // default arguments are to be set in the base class's declaration }; #endif diff --git a/src/file_output.cc b/src/file_output.cc new file mode 100644 index 0000000..0aa2acb --- /dev/null +++ b/src/file_output.cc @@ -0,0 +1,29 @@ +#include "file_output.h" + +void file_output::render() { + for (std::size_t idx = 0; idx < contents.size(); ++idx) { + if (idx % DISPLAY_WIDTH == 0 && idx) + out << std::endl; + + out << (char)contents[idx]; + } +} + +void file_output::print_char(const position &pos, const char ch, + const int attr) { + if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT) + return; + + contents[pos.y * DISPLAY_WIDTH + pos.x] = ch; +} + +void file_output::print_str(const position &pos, const std::string &str, + const int attr) { + if (pos.x >= DISPLAY_WIDTH || pos.y >= DISPLAY_HEIGHT) + return; + + int head = pos.y * DISPLAY_WIDTH + pos.x; + + for (std::size_t i = 0; i < str.length(); ++i) + contents[i + head] = str[i]; +} diff --git a/src/file_output.h b/src/file_output.h new file mode 100644 index 0000000..95fab40 --- /dev/null +++ b/src/file_output.h @@ -0,0 +1,21 @@ +#ifndef __FILE_OUTPUT_H__ +#define __FILE_OUTPUT_H__ + +#include +#include "display.h" + +class file_output final : public display { +private: + std::ofstream out; +public: + file_output(std::ofstream &&new_out); + + void render() override; + void clear() override; + void print_char(const position &pos, + const char ch, const int attr) override; + void print_str(const position &pos, + const std::string &str, const int attr) override; +}; + +#endif