#include "door.h" #include "space.h" #include #include #include // The idea is that this would be defined elsewhere (maybe) int user_score = 0; // NOTE: When run as a door, we always detect CP437 (because that's what Enigma // is defaulting to) void adjust_score(int by) { user_score += by; } door::Panel make_timeout(int mx, int my) { door::ANSIColor yellowred = door::ANSIColor(door::COLOR::YELLOW, door::COLOR::RED, door::ATTR::BOLD); std::string line_text("Sorry, you've been inactive for too long."); int msgWidth = line_text.length() + (2 * 3); // + padding * 2 door::Panel timeout((mx - (msgWidth)) / 2, my / 2 + 4, msgWidth); // place.setTitle(std::make_unique(title), 1); timeout.setStyle(door::BorderStyle::DOUBLE); timeout.setColor(yellowred); door::Line base(line_text); base.setColor(yellowred); std::string pad1(3, ' '); /* std::string pad1(3, '\xb0'); if (door::unicode) { std::string unicode; door::cp437toUnicode(pad1.c_str(), unicode); pad1 = unicode; } */ base.setPadding(pad1, yellowred); // base.setColor(door::ANSIColor(door::COLOR::GREEN, door::COLOR::BLACK)); std::unique_ptr stuff = std::make_unique(base); timeout.addLine(std::make_unique(base)); return timeout; } door::Menu make_main_menu(void) { door::Menu m(5, 5, 25); door::Line mtitle("Space-Ace Main Menu"); door::ANSIColor border_color(door::COLOR::CYAN, door::COLOR::BLUE); door::ANSIColor title_color(door::COLOR::CYAN, door::COLOR::BLUE, door::ATTR::BOLD); m.setColor(border_color); mtitle.setColor(title_color); mtitle.setPadding(" ", title_color); m.setTitle(std::make_unique(mtitle), 1); // m.setColorizer(true, m.setRender(true, door::Menu::makeRender( door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD), door::ANSIColor(door::COLOR::BLUE, door::ATTR::BOLD), door::ANSIColor(door::COLOR::CYAN, door::ATTR::BOLD), door::ANSIColor(door::COLOR::BLUE, door::ATTR::BOLD))); // m.setColorizer(false, m.setRender(false, door::Menu::makeRender( door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD), door::ANSIColor(door::COLOR::WHITE, door::COLOR::BLUE, door::ATTR::BOLD), door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD), door::ANSIColor(door::COLOR::CYAN, door::COLOR::BLUE, door::ATTR::BOLD))); m.addSelection('1', "Play Cards"); m.addSelection('2', "View Scores"); m.addSelection('3', "Drop to DOS"); m.addSelection('4', "Chat with BUGZ"); m.addSelection('H', "Help"); m.addSelection('A', "About this game"); m.addSelection('Q', "Quit"); return m; } door::Panel make_about(void) { door::Panel about(2, 2, 60); about.setStyle(door::BorderStyle::DOUBLE_SINGLE); about.setColor(door::ANSIColor(door::COLOR::YELLOW, door::COLOR::BLUE, door::ATTR::BOLD)); about.addLine(std::make_unique("About This Door", 60)); /* 123456789012345678901234567890123456789012345678901234567890 This door was written by Bugz. It is written in c++, only supports Linux, and replaces opendoors. It's written in c++, and replaces the outdated opendoors library. */ about.addLine( std::make_unique("This door was written by Bugz.", 60)); about.addLine(std::make_unique("", 60)); about.addLine(std::make_unique( "It is written in c++, only support Linux, and replaces", 60)); about.addLine(std::make_unique("opendoors.", 60)); return about; } void display_starfield(int mx, int my, door::Door &door, std::mt19937 &rng) { door << door::reset << door::cls; // display starfield const char *stars[2]; stars[0] = "."; if (door::unicode) { stars[1] = "\u2219"; // "\u00b7"; } else { stars[1] = "\xf9"; // "\xfa"; }; { // Make uniform random distribution between 1 and MAX screen size X/Y std::uniform_int_distribution uni_x(1, mx); std::uniform_int_distribution uni_y(1, my); door::ANSIColor white(door::COLOR::WHITE); door::ANSIColor dark(door::COLOR::BLACK, door::ATTR::BRIGHT); for (int x = 0; x < (mx * my / 100); x++) { door::Goto star_at(uni_x(rng), uni_y(rng)); door << star_at; if (x % 5 < 2) door << dark; else door << white; if (x % 2 == 0) door << stars[0]; else door << stars[1]; } } } void display_space_ace(int mx, int my, door::Door &door) { // space_ace is 72 chars wide, 6 high int sa_x = (mx - 72) / 2; int sa_y = (my - 6) / 2; // output the SpaceAce logo -- centered! for (const auto s : space) { door::Goto sa_at(sa_x, sa_y); door << sa_at; if (door::unicode) { std::string unicode; door::cp437toUnicode(s, unicode); door << unicode; // << door::nl; } else door << s; // << door::nl; sa_y++; } // pause 5 seconds so they can enjoy our awesome logo door.sleep_key(5); } void display_starfield_space_ace(int mx, int my, door::Door &door, std::mt19937 &rng) { display_starfield(mx, my, door, rng); display_space_ace(mx, my, door); door << door::reset; } int main(int argc, char *argv[]) { door::Door door("space-ace", argc, argv); // door << door::reset << door::cls << door::nl; door::ANSIColor ac(door::COLOR::YELLOW, door::ATTR::BOLD); // https://stackoverflow.com/questions/5008804/generating-random-integer-from-a-range std::random_device rd; // only used once to initialise (seed) engine std::mt19937 rng( rd()); // random-number engine used (Mersenne-Twister in this case) // std::uniform_int_distribution uni(min, max); // guaranteed unbiased int mx, my; // Max screen width/height if (door.width == 0) { // screen detect failed, use sensible defaults mx = 80; my = 23; } else { mx = door.width; my = door.height; } // We assume here that the width and height are something crazy like 10x15. :P display_starfield_space_ace(mx, my, door, rng); // for testing inactivity timeout door.inactivity = 10; door::Panel timeout = make_timeout(mx, my); door::Menu m = make_main_menu(); int r = m.choose(door); // need to reset the colors. (whoops!) door << door::reset; if (r == -1) { TIMEOUT: door.log("TIMEOUT"); // mx, my door::ANSIColor yellowred = door::ANSIColor( door::COLOR::YELLOW, door::COLOR::RED, door::ATTR::BOLD); std::string line_text("Sorry, you've been inactive for too long."); int msgWidth = line_text.length() + (2 * 3); // + padding * 2 door::Panel timeout((mx - (msgWidth)) / 2, my / 2 + 4, msgWidth); // place.setTitle(std::make_unique(title), 1); timeout.setStyle(door::BorderStyle::DOUBLE); timeout.setColor(yellowred); door::Line base(line_text); base.setColor(yellowred); std::string pad1(3, ' '); /* std::string pad1(3, '\xb0'); if (door::unicode) { std::string unicode; door::cp437toUnicode(pad1.c_str(), unicode); pad1 = unicode; } */ base.setPadding(pad1, yellowred); // base.setColor(door::ANSIColor(door::COLOR::GREEN, door::COLOR::BLACK)); std::unique_ptr stuff = std::make_unique(base); timeout.addLine(std::make_unique(base)); door << timeout << door::reset << door::nl << door::nl; return 0; } display_starfield(mx, my, door, rng); // WARNING: After starfield, cursor position is random! door << door::Goto(1, 9); // door::nl << door::nl; // door::cls; door << "Hello, " << door.username << ", you chose option " << r << "!" << door::nl; door << "Press a key..."; r = door.sleep_key(door.inactivity); if (r == -1) goto TIMEOUT; door << door::nl; door::Panel about = make_about(); about.set((mx - 60) / 2, (my - 5) / 2); door << about; door << door::reset << door::nl << "Press another key..."; r = door.sleep_key(door.inactivity); if (r == -1) goto TIMEOUT; door << door::nl; // door << door::reset << door::cls; display_starfield(mx, my, door, rng); door << m << door::reset << door::nl << "This is what the menu looked liked!" << door::nl; // Normal DOOR exit goes here... door << door::nl << "Returning you to the BBS, please wait..." << door::nl; sleep(2); return 0; }