#include #include #include #include #include /* For single player mode. */ #include #include #include #include #include "../../server/src/network_manager.h" #include "terminal.h" #include "gfx/shape_renderer.h" #include "ui/desktop.h" #include "ui/ui_window.h" void run_server(void) { try { NetworkManager server; server.start(1337); /* * Server's start() method is non-blocking, but NetworkManager * object must be kept alive. We'll just loop forever and let the OS * clean up the thread when main exits ;) */ while(true) { std::this_thread::sleep_for(std::chrono::seconds(5)); } } catch(const std::exception& e) { fprintf(stderr, "Single-player server thread exception: %s\n", e.what()); } } const int SCREEN_WIDTH = 1280; const int SCREEN_HEIGHT = 720; int main(int argc, char** argv) { if(argc > 1 && std::string(argv[1]) == "-sp") { fprintf(stdout, "Starting in single-player mode...\n"); std::thread server_thread(run_server); server_thread.detach(); fprintf(stdout, "Waiting for server initialise...\n"); std::this_thread::sleep_for(std::chrono::milliseconds(200)); } /* Init SDL. */ if(!SDL_Init(SDL_INIT_VIDEO)) { printf("SDL could not initialise! SDL_ERROR: %s\n", SDL_GetError()); return 1; } /* Set OpenGL attributes. */ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); /* Create a window. */ SDL_Window* window = SDL_CreateWindow( "Bettola Client", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL ); if(window == NULL) { printf("Unable to create window! SDL_ERROR: %s\n", SDL_GetError()); return 1; } /* Create OpenGL context. */ SDL_GLContext context = SDL_GL_CreateContext(window); if(context == NULL) { printf("OpenGL context could not be created! SDL_ERROR: %s\n", SDL_GetError()); return 1; } /* Initialise GLEW. */ glewExperimental = GL_TRUE; GLenum glewError = glewInit(); if (glewError != GLEW_OK) { /* NOTE: * Dear future self, or other intrepid developer: * In some environments (like the Fedora VM I tested), * glewInit() returns an error here even when the context is valid. * This is a known quirk. We print the error but continue anyway, * because it's not fatal. Don't "fix" this by making it exit. Thank you. * It's GLEW, not you. */ fprintf(stderr, "Warning: glewInit failed with error code %u: %s. Attempting to continue anyway.\n", glewError, glewGetErrorString(glewError)); } /* Configure OpenGL. */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* Listen for text input. */ SDL_StartTextInput(window); /* Init text renderer. */ TextRenderer* txt_render_instance = new TextRenderer(SCREEN_WIDTH, SCREEN_HEIGHT); txt_render_instance->load_font("assets/fonts/hack/Hack-Regular.ttf", 14); /* Init shape renderer. */ ShapeRenderer* shape_renderer_instance = new ShapeRenderer(SCREEN_WIDTH, SCREEN_HEIGHT); /* Create terminal. */ auto term = std::make_unique(); /* Create UI window and pass it a terminal. */ auto test_window = std::make_unique("Terminal", 100, 100, 800, 500); test_window->set_content(std::move(term)); /* Create desktop and add the window. */ auto desktop = std::make_unique(); desktop->add_window(std::move(test_window)); /* timer for cursor blink. */ Uint32 last_blink_time = 0; bool show_cursor = true; bool running = true; while(running) { /* Event handling. */ SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_EVENT_QUIT) { running = false; } desktop.get()->handle_event(&event); } desktop.get()->update(); Uint32 current_time = SDL_GetTicks(); if(current_time - last_blink_time > 500) { /* Every 500ms. */ show_cursor = !show_cursor; last_blink_time = current_time; } /* Clear screen. */ glClearColor(0.1f, 0.1f, 0.1, 1.0f); glClear(GL_COLOR_BUFFER_BIT); desktop.get()->render(shape_renderer_instance, txt_render_instance, SCREEN_HEIGHT, show_cursor); /* It's really odd to call it SwapWindow now, rather than SwapBuffer. */ SDL_GL_SwapWindow(window); } /* Cleanup. */ desktop.reset(); delete shape_renderer_instance; delete txt_render_instance; SDL_GL_DestroyContext(context); SDL_DestroyWindow(window); SDL_Quit(); return 0; }