fissh

termios terminal aquarium. demo at ssh://fish@kloet.net
Download | Log | Files | Refs

Config.cpp (5543B)


      1 #include "Config.h"
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <getopt.h>
      5 #include <iostream>
      6 
      7 AquariumConfig g_config;
      8 
      9 void printUsage(const char *program_name) {
     10   std::cout << "Usage: " << program_name << " [OPTIONS]\n\n";
     11   std::cout << "Aquarium screensaver with customizable settings\n\n";
     12   std::cout << "OPTIONS:\n";
     13   std::cout << "  -h, --help                Show this help message\n";
     14   std::cout
     15       << "  -f, --fish COUNT          Number of initial fish (default: auto)\n";
     16   std::cout << "  -s, --seaweed COUNT       Number of seaweed plants (default: "
     17                "auto)\n";
     18   std::cout << "  -b, --max-bubbles COUNT   Maximum bubbles on screen "
     19                "(default: 50)\n";
     20   std::cout << "  -d, --delay MS            Frame delay in milliseconds "
     21                "(default: 100)\n";
     22   std::cout << "  -r, --bubble-rate RATE    Fish bubble spawn rate 1/N "
     23                "(default: 10)\n";
     24   std::cout << "  -m, --max-entities COUNT  Maximum entities on screen "
     25                "(default: 200)\n";
     26   std::cout << "  --no-big-entities         Disable ships, whales, and sea "
     27                "monsters\n";
     28   std::cout << "  --no-bubbles              Disable bubble generation\n";
     29   std::cout << "  --no-colors               Disable colors (monochrome mode)\n";
     30   std::cout << "  --no-bold                 Disable bold text\n";
     31   std::cout << "  --show-fps                Display FPS counter\n";
     32   std::cout << "  --show-count              Display entity count\n";
     33   std::cout << "  --debug                   Enable debug mode\n";
     34   std::cout << "\nShort options can be combined: -f20 -s5 -d50\n";
     35   std::cout << "Long options accept = syntax: --fish=20 --delay=50\n";
     36   std::cout << "\nExamples:\n";
     37   std::cout << "  " << program_name
     38             << " -f20 -s5 -d50         # Fast aquarium with lots of fish\n";
     39   std::cout << "  " << program_name
     40             << " --fish=10 --no-colors # 10 fish, monochrome\n";
     41   std::cout << "  " << program_name
     42             << " --debug --show-fps    # Debug mode with FPS\n";
     43 }
     44 
     45 bool parseArguments(int argc, char *argv[]) {
     46   // Define long options
     47   static const struct option long_options[] = {
     48       {"help", no_argument, nullptr, 'h'},
     49       {"fish", required_argument, nullptr, 'f'},
     50       {"seaweed", required_argument, nullptr, 's'},
     51       {"max-bubbles", required_argument, nullptr, 'b'},
     52       {"delay", required_argument, nullptr, 'd'},
     53       {"bubble-rate", required_argument, nullptr, 'r'},
     54       {"max-entities", required_argument, nullptr, 'm'},
     55       {"no-big-entities", no_argument, nullptr, 'B'},
     56       {"no-bubbles", no_argument, nullptr, 'N'},
     57       {"no-colors", no_argument, nullptr, 'C'},
     58       {"no-bold", no_argument, nullptr, 'O'},
     59       {"show-fps", no_argument, nullptr, 'F'},
     60       {"show-count", no_argument, nullptr, 'S'},
     61       {"debug", no_argument, nullptr, 'D'},
     62       {nullptr, 0, nullptr, 0}};
     63 
     64   // Short options string - : after letter means it takes an argument
     65   const char *short_options = "hf:s:b:d:r:m:BNCOFSD";
     66 
     67   int option;
     68   int option_index = 0;
     69 
     70   // Reset getopt state (important for testing)
     71   optind = 1;
     72 
     73   while ((option = getopt_long(argc, argv, short_options, long_options,
     74                                &option_index)) != -1) {
     75     switch (option) {
     76     case 'h':
     77       printUsage(argv[0]);
     78       return false;
     79 
     80     case 'f':
     81       g_config.initial_fish_count = std::atoi(optarg);
     82       if (g_config.initial_fish_count < -1) {
     83         std::cerr << "Error: Fish count must be >= -1\n";
     84         return false;
     85       }
     86       break;
     87 
     88     case 's':
     89       g_config.initial_seaweed_count = std::atoi(optarg);
     90       if (g_config.initial_seaweed_count < -1) {
     91         std::cerr << "Error: Seaweed count must be >= -1\n";
     92         return false;
     93       }
     94       break;
     95 
     96     case 'b':
     97       g_config.max_bubbles = std::atoi(optarg);
     98       if (g_config.max_bubbles < 0) {
     99         std::cerr << "Error: Max bubbles must be >= 0\n";
    100         return false;
    101       }
    102       break;
    103 
    104     case 'd':
    105       g_config.frame_delay_ms = std::atoi(optarg);
    106       if (g_config.frame_delay_ms < 1) {
    107         std::cerr << "Error: Frame delay must be >= 1ms\n";
    108         return false;
    109       }
    110       break;
    111 
    112     case 'r':
    113       g_config.fish_bubble_rate = std::atoi(optarg);
    114       if (g_config.fish_bubble_rate < 1) {
    115         std::cerr << "Error: Bubble rate must be >= 1\n";
    116         return false;
    117       }
    118       break;
    119 
    120     case 'm':
    121       g_config.max_entities = std::atoi(optarg);
    122       if (g_config.max_entities < 1) {
    123         std::cerr << "Error: Max entities must be >= 1\n";
    124         return false;
    125       }
    126       break;
    127 
    128     case 'B':
    129       g_config.enable_big_entities = false;
    130       break;
    131 
    132     case 'N':
    133       g_config.enable_bubbles = false;
    134       break;
    135 
    136     case 'C':
    137       g_config.use_colors = false;
    138       break;
    139 
    140     case 'O':
    141       g_config.use_bold = false;
    142       break;
    143 
    144     case 'F':
    145       g_config.show_fps = true;
    146       break;
    147 
    148     case 'S':
    149       g_config.show_entity_count = true;
    150       break;
    151 
    152     case 'D':
    153       g_config.debug_mode = true;
    154       break;
    155 
    156     case '?':
    157       // getopt_long already printed an error message
    158       std::cerr << "Use --help for usage information\n";
    159       return false;
    160 
    161     default:
    162       std::cerr << "Error: Unexpected option character\n";
    163       return false;
    164     }
    165   }
    166 
    167   // Check for non-option arguments
    168   if (optind < argc) {
    169     std::cerr << "Error: Unexpected argument: " << argv[optind] << "\n";
    170     std::cerr << "Use --help for usage information\n";
    171     return false;
    172   }
    173 
    174   return true;
    175 }