summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/diargs.cpp84
-rw-r--r--src/game.cpp9
-rw-r--r--src/main.cpp27
-rw-r--r--src/system.cpp73
4 files changed, 135 insertions, 58 deletions
diff --git a/src/diargs.cpp b/src/diargs.cpp
new file mode 100644
index 0000000..b7aa79e
--- /dev/null
+++ b/src/diargs.cpp
@@ -0,0 +1,84 @@
+/**
+ * diargs.cpp
+ * Copyright (c) 2022 Jon Santmyer <jon@jonsantmyer.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "diargs.hpp"
+#include <string_view>
+#include <list>
+
+namespace diargs
+{
+
+ArgumentParser::ArgumentParser(
+ void (*failfunc)(int),
+ ArgumentList &arguments,
+ ArgsPair argcv)
+{
+ /*Raw c strings passed to string_view for safety*/
+ std::vector<std::string_view> argv(argcv.argc);
+ for(int arg = 0; arg < argcv.argc; arg++) {
+ argv[arg] = std::string_view(argcv.argv[arg]);
+ }
+
+ /*Skip the first argument because it will always be the path to the program*/
+ for(auto it = argv.begin() + 1; it != argv.end(); it++) {
+ if(it->at(0) == '-') { /*Argument could be shortform*/
+ if(it->at(1) == '-') { /*Argument is longform*/
+ std::string_view parsing = std::string_view(it->data() + 2);
+ if(parsing.size() == 0) continue;
+ for(auto &argdef : arguments.arguments) {
+ if(argdef->longform != parsing) continue;
+ auto newit = argdef->parse(argv, it);
+ if(newit == std::nullopt) {
+ failfunc(-1);
+ return;
+ }
+ it = newit.value_or(argv.end());
+ break;
+ }
+ continue;
+ }
+ std::string_view parsing = (*it);
+ for(char c : parsing) {
+ for(auto &argdef : arguments.arguments) {
+ if(argdef->shortform != c) continue;
+ auto newit = argdef->parse(argv, it);
+ if(newit == std::nullopt) {
+ failfunc(-1);
+ return;
+ }
+ it = newit.value_or(argv.end());
+ }
+ }
+ continue;
+ } /*When argument is unmarked, it's an ordered type*/
+ for(auto argit = arguments.arguments.begin();
+ argit != arguments.arguments.end();
+ argit++) {
+ if((*argit)->shortform != 0 || !(*argit)->longform.empty()) continue;
+ it = (*argit)->parse(argv, it).value_or(argv.end());
+ arguments.arguments.erase(argit);
+ break;
+ }
+ }
+}
+
+}
diff --git a/src/game.cpp b/src/game.cpp
index b1d0b00..d992a99 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -21,7 +21,7 @@ Game::State Game::m_state = State::RUNNING;
Game::WindowContexts Game::contexts;
void
-Game::setup(unsigned w, unsigned h)
+Game::setup(unsigned w, unsigned h, const std::string &sysname)
{
KeyMan::loadKeybindsFrom("keybinds.csv");
@@ -32,22 +32,21 @@ Game::setup(unsigned w, unsigned h)
unsigned int viewh = h - 1;
unsigned int infow = 24;
unsigned int infoh = 12;
- unsigned int timeh = 10;
+ unsigned int timeh = h - infoh;
TimeMan::init();
m_contexts.emplace(WINCTX_GAME, WindowContext());
+ m_contexts.emplace(WINCTX_TITLE, WindowContext());
WindowContext *gameContext = &m_contexts[WINCTX_GAME];
gameContext->registerWindow(WINDOW_SYSTEMVIEW_ID, "System View", infow, 0, w - infow, viewh);
gameContext->registerWindow(WINDOW_BODYINFO_ID, "Body Info", 0, 0, infow, infoh);
- gameContext->registerWindow(WINDOW_EVENTS_ID, "Events", 0, infoh, infow, viewh - infoh - timeh);
gameContext->registerWindow(WINDOW_TIMEMAN_ID, "Time", 0, viewh - timeh, infow, timeh);
-
gameContext->registerWindow(WINDOW_SYSTEMVIEW_SEARCH_ID, "Search", infow, 0, (w - infow) / 4, viewh, true);
m_currentContext = WINCTX_GAME;
m_camera = std::make_unique<Camera>((*gameContext)[WINDOW_SYSTEMVIEW_ID].screen());
- m_system = std::make_unique<System>();
+ m_system = std::make_unique<System>(sysname);
m_systemView.view(m_system.get());
KeyMan::registerBind('\x1B', BIND_G_ESCAPE, CTX_GLOBAL, "Escape from focused searchbox / window");
diff --git a/src/main.cpp b/src/main.cpp
index 9ff09a6..5fafaf8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,21 +1,42 @@
#include <iostream>
#include "game.hpp"
+#include "diargs.hpp"
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
+void
+printusage(int err)
+{
+ std::cout << "systemviewer " << VERSION << std::endl <<
+ "Usage: systemviewer [OPTION]... [FILE]" << std::endl <<
+ "With no FILE, FILE is assumed to be data/sol.csv" << std::endl <<
+ "-h --help : print this message" << std::endl;
+
+ std::exit(err);
+}
+
int
main(int argc, char **argv)
{
- (void)argc;
- (void)argv;
+ std::string system = "dat/sol.csv";
+ bool helpflag;
+
+ diargs::ArgsPair args{argc, argv};
+ diargs::ArgumentList arglist(
+ diargs::OrderedArgument<std::string>(system),
+ diargs::ToggleArgument<bool>("help", 'h', helpflag, true)
+ );
+ diargs::ArgumentParser(printusage, arglist, args);
+
+ if(helpflag) printusage(0);
struct winsize w;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
fcntl(STDIN_FILENO, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
- Game::setup(w.ws_col, w.ws_row);
+ Game::setup(w.ws_col, w.ws_row, system);
while(Game::running()) {
Game::turn();
diff --git a/src/system.cpp b/src/system.cpp
index 974d0dc..61cb8be 100644
--- a/src/system.cpp
+++ b/src/system.cpp
@@ -11,7 +11,7 @@
static double G = 6.6743 * std::pow(10, -11);
-ecs::Entity &
+void
System::addOrbital(const std::string &name,
const std::string &orbitingName,
unsigned long a,
@@ -25,64 +25,36 @@ System::addOrbital(const std::string &name,
w *= (std::numbers::pi / 180.0);
SystemTreeNode *treeNode = getNode(orbitingName);
- ecs::Entity &newOrbital = m_entityMan.newEntity()
+ ecs::Entity newOrbital = m_entityMan.newEntity()
.addComponent(ecs::PositionComponent{vex::vec2<long>{0, 0}})
.addComponent(ecs::MassComponent{m})
- .addComponent(ecs::OrbitalComponent{.origin = treeNode->entityId, .a = (long)a, .e = e, .w = w, .M = M, .T = 0, .v = 0})
.addComponent(ecs::RenderCircleComponent{r})
.addComponent(ecs::NameComponent{name});
- treeNode->children.push_back({newOrbital.id, {}});
- return newOrbital;
+ if(treeNode != nullptr) {
+ newOrbital.addComponent(ecs::OrbitalComponent{.origin = (unsigned)treeNode->entityId, .a = (long)a, .e = e, .w = w, .M = M, .T = 0, .v = 0});
+ treeNode->children.push_back({(int)newOrbital.id, {}});
+ }else{
+ m_systemTree.entityId = newOrbital.id;
+ }
}
-System::System()
+System::System(const std::string &name)
{
- auto sol = m_entityMan.newEntity()
- .addComponent(ecs::PositionComponent{vex::vec2<long>{0, 0}})
- .addComponent(ecs::MassComponent{unit::solMass})
- .addComponent(ecs::RenderCircleComponent{695700})
- .addComponent(ecs::NameComponent{"Sol"});
- m_systemTree.entityId = sol.id;
-
- csv::CSVFile<',', std::string, std::string, double, double, double, double, double, double> planetData("data/sol_planets.csv");
- for(auto &planet : planetData.get()) {
- std::string name = std::get<0>(planet);
- std::string orbiting = std::get<1>(planet);
- double sma = std::get<2>(planet) * unit::AU;
- double e = std::get<3>(planet);
- unit::Mass m = unit::earthMass * std::get<4>(planet);
- double r = std::get<5>(planet) * unit::earthRad;
- double M = std::get<6>(planet);
- double w = std::get<7>(planet);
+ m_systemTree.entityId = -1;
+ csv::CSVFile<',', std::string, std::string, double, double, double, double, double, double, std::string> bodyData(name);
+ for(auto &body : bodyData.get()) {
+ std::string name = std::get<0>(body);
+ std::string orbiting = std::get<1>(body);
+ double sma = std::get<2>(body) * unit::AU;
+ double e = std::get<3>(body);
+ unit::Mass m = unit::earthMass * std::get<4>(body);
+ double r = std::get<5>(body) * unit::earthRad;
+ double M = std::get<6>(body);
+ double w = std::get<7>(body);
+
+ if(name == "Missing") name = std::get<8>(body);
addOrbital(name, orbiting, sma, e, m, r, M, w);
}
-
- csv::CSVFile<',', std::string, std::string, double, double, double, double, double, double> satelliteData("data/sol_satellites.csv");
- for(auto &satellite : satelliteData.get()) {
- std::string name = std::get<0>(satellite);
- std::string orbiting = std::get<1>(satellite);
- double sma = std::get<2>(satellite) * unit::AU;
- double e = std::get<3>(satellite);
- unit::Mass m = unit::earthMass * std::get<4>(satellite);
- double r = std::get<5>(satellite) * unit::earthRad;
- double M = std::get<6>(satellite);
- double w = std::get<7>(satellite);
- addOrbital(name, orbiting, sma, e, m, r, M, w);
- }
-
- csv::CSVFile<',', std::string, double, double, double, double, double, std::string> asteroidData("data/sol_asteroids.csv");
- for(auto &asteroid : asteroidData.get()) {
- std::string name = std::get<0>(asteroid);
- if(name == "Missing") name = std::get<6>(asteroid);
- addOrbital(name,
- "Sol",
- (unsigned long)(std::get<1>(asteroid) * unit::AU),
- std::get<2>(asteroid),
- unit::Mass(0),
- (unsigned)std::get<3>(asteroid),
- std::get<4>(asteroid),
- std::get<5>(asteroid));
- }
}
constexpr static double tau = std::numbers::pi * 2;
@@ -161,6 +133,7 @@ System::traverseSystemTree(SystemTreeNode &node, const std::string &name)
System::SystemTreeNode *
System::getNode(const std::string &name)
{
+ if(m_systemTree.entityId == -1) return nullptr;
SystemTreeNode *treeRes = traverseSystemTree(m_systemTree, name);
if(treeRes == nullptr)
treeRes = &m_systemTree;