cplusplus2x.Examples/C++20/MasterX/src/main.cpp
Source: cplusplus2x.Examples/C++20/MasterX/src/main.cpp
/*
MasterX System written by Jared Bruni
(C) 2024 LostSideDead Software
https://lostsidedead.biz
*/
#include "SDL.h"
#include "argz.hpp"
#include "dimension.hpp"
#include "splash.hpp"
#include "window.hpp"
#include <iostream>
#include <limits.h>
#include <memory>
#include <vector>
#ifdef _WIN32
#include <windows.h>
#endif
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
std::vector<std::unique_ptr<mx::Screen>> *screens;
int cur_screen = 0;
mx::mxApp *p_app = nullptr;
void setScreen(int scr) {
if (scr >= 0 && scr < static_cast<int>(screens->size()))
cur_screen = scr;
else {
std::cerr << "Error screen out of bounds\n";
}
}
void draw(mx::mxApp &app) {
SDL_SetRenderDrawColor(app.ren, 0, 0, 0, 255);
SDL_RenderClear(app.ren);
SDL_SetRenderTarget(app.ren, app.tex);
SDL_SetRenderDrawColor(app.ren, 0, 0, 0, 255);
SDL_RenderClear(app.ren);
(*screens)[cur_screen]->draw(app);
SDL_RenderCopy(app.ren, app.tex, nullptr, nullptr);
SDL_RenderPresent(app.ren);
}
void eventProc() {
static SDL_Event e;
while (SDL_PollEvent(&e)) {
if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) {
p_app->active = false;
}
(*screens)[cur_screen]->event(*p_app, e);
}
draw(*p_app);
}
void init(mx::mxApp &app) {
screens->push_back(std::make_unique<mx::Splash>(app));
screens->push_back(std::make_unique<mx::Dimension>(app));
}
#ifdef FOR_WASM
std::string cur_path = "/assets";
#else
std::string cur_path = "assets";
#endif
std::string getPath(const std::string &name) {
return cur_path + "/" + name;
}
std::optional<std::string> get_current_directory() {
#ifdef _WIN32
char cwd[MAX_PATH];
if (GetCurrentDirectoryA(sizeof(cwd), cwd)) {
return std::string(cwd);
} else {
return std::nullopt;
}
#elif !defined(FOR_WASM)
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
return std::string(cwd);
} else {
return std::nullopt;
}
#endif
return std::nullopt;
}
SDL_Texture *loadTexture(mx::mxApp &app, const std::string &name) {
int w, h;
return loadTexture(app, name, w, h);
}
extern SDL_Texture *loadTexture(mx::mxApp &app, const std::string &name, int &w, int &h) {
SDL_Surface *surf = SDL_LoadBMP(getPath(name).c_str());
if (!surf) {
std::cerr << "Error loading surface; " << getPath(name) << "\n";
exit(EXIT_FAILURE);
}
w = surf->w;
h = surf->h;
SDL_Texture *tex = SDL_CreateTextureFromSurface(app.ren, surf);
if (!tex) {
std::cerr << "Error creating texture from surface: " << name << "\n";
exit(EXIT_FAILURE);
}
return tex;
}
void quit() {
std::cout << "MasterX System: Exiting...\n";
SDL_ShowCursor(SDL_TRUE);
TTF_Quit();
SDL_Quit();
}
int main(int argc, char **argv) {
Argz<std::string> argz(argc, argv);
argz.addOptionSingleValue('p', "path to assets").addOptionDoubleValue('P', "path", "path to assets").addOptionSingleValue('v', "info").addOptionSingle('h', "info").addOptionSingle('f', "set fullscreen").addOptionDouble('F', "fullscreen", "set fullscreen");
std::string path;
bool full = false;
int value = 0;
Argument<std::string> arg;
try {
while ((value = argz.proc(arg)) != -1) {
switch (value) {
case 'h':
case 'v':
argz.help(std::cout);
exit(EXIT_SUCCESS);
break;
case 'p':
case 'P':
path = arg.arg_value;
break;
case 'f':
case 'F':
full = true;
break;
}
}
} catch (const ArgException<std::string> &e) {
std::cerr << "Syntax Error: " << e.text() << "\n";
}
if (path.length() > 0) {
std::cout << "MasterX System: path set to: " << path << "\n";
cur_path = path;
} else {
#ifndef FOR_WASM
argz.help(std::cout);
exit(EXIT_FAILURE);
#endif
}
mx::mxApp app;
p_app = &app;
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
if (TTF_Init() < 0) {
std::cerr << "Error initializing SDL_ttf: " << TTF_GetError() << "\n";
return 1;
}
atexit(quit);
SDL_ShowCursor(SDL_FALSE);
std::vector<std::unique_ptr<mx::Screen>> screen_obj;
screens = &screen_obj;
if (!app.init("MasterX", 1280, 720)) {
exit(EXIT_FAILURE);
return 1;
}
init(app);
if (full) {
app.set_fullscreen(app.win, true);
}
app.active = true;
#ifndef FOR_WASM
while (app.active == true) {
eventProc();
}
#else
emscripten_set_main_loop(eventProc, 0, 1);
#endif
return 0;
}