diff --git a/README.md b/README.md index 754d16d..b5861be 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ The terminal supports a subset of VT220, and uses SDL-GPU for rendering. For the The terminal reads the "default" file in its directory which should just contain the path to a JSON file. An example is given in default and config/ located in src/resources. -A release is planned in the near future. +The current version is 0.2.0, it is still in active development and may not replace your terminal application. ## Features diff --git a/src/ArgumentParser.cpp b/src/ArgumentParser.cpp new file mode 100644 index 0000000..ffde9bb --- /dev/null +++ b/src/ArgumentParser.cpp @@ -0,0 +1,113 @@ +#include +#include "ArgumentParser.h" + +inline bool expectArg(int current, int argc, std::string error) +{ + if (!(current < argc)) + { + std::cerr << "[ERROR] expected argumnet for: " << error << std::endl; + exit(-1); + } +} + +inline void unrecognisedArg(std::string arg) +{ + std::cerr << "[ERROR] unrecognised argument: " << arg << std::endl; + exit(-1); +} + +inline void invalidArg(std::string arg, std::string value) +{ + std::cerr << "[ERROR] Invalid argument to '" << arg << "': " << value << std::endl; + exit(-1); +} + +void ArgumentParser::Parse(int argc, char** argv) +{ + for (int i = 1; i < argc; i++) + { + std::string current_arg = std::string(argv[i]); + if (this->parser_state == ARGUMENT_ATTR) + { + this->argmap[this->processing_arg] = current_arg; + this->parser_state = ARGUMENT_NORMAL; + } + else + { + if (current_arg[0] != '-') + { + /* If this is the first argument and doesnt begin with a dash, just store it */ + if (this->parser_state == ARGUMENT_LIST_BEGIN) + { + this->argmap["first_argument"] = current_arg; + this->argmap[this->first_arg] = current_arg; + } + else + { + unrecognisedArg(current_arg); + } + } + else + { + /* Remove the '-' */ + current_arg.erase(0, 1); + if (std::find(this->expected_args.begin(), this->expected_args.end(), current_arg) != this->expected_args.end()) + { + this->parser_state = ARGUMENT_ATTR; + this->processing_arg = current_arg; + } + else + { + unrecognisedArg(current_arg); + } + } + } + } +} + +void ArgumentParser::AddArgument(std::string arg, bool first_arg) +{ + this->expected_args.push_back(arg); + if (first_arg) + { + this->first_arg = arg; + } +} + +void ArgumentParser::GetArgument(std::string arg, std::string& result) +{ + if (this->argmap.find(arg) != this->argmap.end()) + { + result = this->argmap[arg]; + } +} + +void ArgumentParser::GetArgument(std::string arg, int& result) +{ + if (this->argmap.find(arg) != this->argmap.end()) + { + try + { + result = std::stoi(this->argmap[arg]); + } + catch (...) + { + invalidArg(arg, this->argmap[arg]); + } + } +} + +void ArgumentParser::GetArgument(std::string arg, float& result) +{ + if (this->argmap.find(arg) != this->argmap.end()) + { + try + { + result = std::stof(this->argmap[arg]); + } + catch (...) + { + invalidArg(arg, this->argmap[arg]); + } + } +} \ No newline at end of file diff --git a/src/ArgumentParser.h b/src/ArgumentParser.h new file mode 100644 index 0000000..6dc973f --- /dev/null +++ b/src/ArgumentParser.h @@ -0,0 +1,35 @@ +/* + Nicely written class for parsing arguments. Heh, just kidding, I wrote this for some C++ practice. +*/ + +#ifndef ARGUMENT_PARSER_H +#define ARGUMENT_PARSER_H + +#include + +#include "CRTermConfig.h" + +typedef enum +{ + ARGUMENT_LIST_BEGIN, + ARGUMENT_NORMAL, + ARGUMENT_ATTR +} ARGUMENT_PARSER_STATE; + +class ArgumentParser +{ +public: + ARGUMENT_PARSER_STATE parser_state = ARGUMENT_LIST_BEGIN; + std::unordered_map argmap; + std::vector expected_args; + std::string first_arg; + std::string processing_arg; + ArgumentParser(void) { }; + void Parse(int argc, char** argv); + void AddArgument(std::string argument, bool first_arg = false); + void GetArgument(std::string, std::string&); + void GetArgument(std::string, float&); + void GetArgument(std::string, int&); +}; + +#endif diff --git a/src/CRTerm.cpp b/src/CRTerm.cpp index 3de52ce..bd7b1fb 100644 --- a/src/CRTerm.cpp +++ b/src/CRTerm.cpp @@ -8,6 +8,7 @@ #include "imgui_impl_sdl2.h" #include "imgui_impl_opengl3.h" +#define SDL_MAIN_HANDLED #include "SDL_gpu.h" #include "CustomTitleBar.h" #include "Shaders.h" @@ -18,16 +19,31 @@ #include "ConfigEditor.h" #include "ConfigSelector.h" #include "ContextMenu.h" +#include "ArgumentParser.h" /* SDLmain requires this. It seems to define its own main. */ #undef main void menuCallBack(int, void*); -int main() +int main(int argc, char* argv[]) { /* Read the path of the configuration JSON from "default" and then load it */ CRTermConfiguration* cfg = new CRTermConfiguration(GetDefaultConfigJSON()); + + /* Parse arguments */ + ArgumentParser arg_parse; + arg_parse.AddArgument("fs"); + arg_parse.AddArgument("cw"); + arg_parse.AddArgument("ch"); + arg_parse.AddArgument("cmd", true); + + arg_parse.Parse(argc, argv); + + arg_parse.GetArgument("cw", cfg->console_width); + arg_parse.GetArgument("ch", cfg->console_height); + arg_parse.GetArgument("fs", cfg->font_scale); + arg_parse.GetArgument("cmd", cfg->shell_command); /* Calculate the required screen resolution from the configuration */ int resolution_x = (int)(cfg->font_width * cfg->font_scale * cfg->console_width) + 2 * SIDES_WIDTH; diff --git a/src/CRTerm.h b/src/CRTerm.h index 7970daa..471af05 100644 --- a/src/CRTerm.h +++ b/src/CRTerm.h @@ -1,7 +1,7 @@ #ifndef CRTERM_H #define CRTERM_H -#define CRTERM_VERSION_STRING "CRTerm 0.1.0" +#define CRTERM_VERSION_STRING "CRTerm 0.2.0" #define CRTERM_CREDIT_STRING "(C) Siddharth Gautam, 2023\nThis software comes with NO WARRANTY.\n" #endif \ No newline at end of file diff --git a/src/CRTerm.rc b/src/CRTerm.rc index 0ff6063..696fce5 100644 Binary files a/src/CRTerm.rc and b/src/CRTerm.rc differ diff --git a/src/CRTerm.vcxproj b/src/CRTerm.vcxproj index de43169..35f399f 100644 --- a/src/CRTerm.vcxproj +++ b/src/CRTerm.vcxproj @@ -130,15 +130,17 @@ stdcpp17 - Console + Windows true true true $(ProjectDir)lib\SDL2;$(ProjectDir)lib\SDL2_gpu;%(AdditionalLibraryDirectories) - SDL2main.lib;SDL2.lib;SDL2_gpu.lib;winmm.lib;Dwmapi.lib;%(AdditionalDependencies) + SDL2.lib;SDL2main.lib;SDL2_gpu.lib;winmm.lib;Dwmapi.lib;%(AdditionalDependencies) + mainCRTStartup + @@ -160,6 +162,7 @@ + @@ -280,8 +283,8 @@ - - + + diff --git a/src/CRTerm.vcxproj.filters b/src/CRTerm.vcxproj.filters index f79bdb9..0a1d70b 100644 --- a/src/CRTerm.vcxproj.filters +++ b/src/CRTerm.vcxproj.filters @@ -90,6 +90,9 @@ Source Files + + Source Files + @@ -437,6 +440,9 @@ Source Files + + Source Files + @@ -444,10 +450,10 @@ - + Resource Files - + Resource Files diff --git a/src/crterm.ico b/src/crterm.ico new file mode 100644 index 0000000..8392c0a Binary files /dev/null and b/src/crterm.ico differ diff --git a/src/icon.png b/src/icon.png new file mode 100644 index 0000000..38cd985 Binary files /dev/null and b/src/icon.png differ diff --git a/src/resource.h b/src/resource.h index 4e71d59..af8eddb 100644 --- a/src/resource.h +++ b/src/resource.h @@ -2,12 +2,13 @@ // Microsoft Visual C++ generated include file. // Used by CRTerm.rc // +#define IDI_ICON1 104 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_RESOURCE_VALUE 105 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/src/resources/config/default_cmd.json b/src/resources/config/default_cmd.json index f926609..4e96bcc 100644 --- a/src/resources/config/default_cmd.json +++ b/src/resources/config/default_cmd.json @@ -10,7 +10,7 @@ "crt_shader": "shaders/crt", "bell": "bell.wav", "crt_warp": 0.0, - "shell_command": "cmd.exe %USERPROFILE%", + "shell_command": "cmd /K \"cd %userprofile%\"", "blink_interval": 300, "default_fg": 2, "default_bg": 2,