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 }