#include #include #include #include #include #include #include "Base.hpp" #ifndef __unused #define __unused __attribute__((unused)) #endif std::map mysterious_pointers; #include unsigned int motor::al::Buffer::nr_buffers = 0; unsigned int motor::al::Source::nr_sources = 0; template struct GenericMain { private: motor::al::AL al_context; int screen_width = 0; int screen_height = 0; void init_sdl(bool const fullscreen, int const wanted_resolution_width, int const wanted_resolution_height){ SDL_Init(SDL_INIT_VIDEO); char const * caption = "onegame"; SDL_WM_SetCaption(caption, caption); auto const double_buffer_result = SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true); if(double_buffer_result){ CERR << "Failed to enable double_buffering" << std::endl; } SDL_Surface * screen = nullptr; if(fullscreen){ screen = SDL_SetVideoMode(0, 0, 32, SDL_OPENGL | SDL_FULLSCREEN); } else { screen = SDL_SetVideoMode(wanted_resolution_width, wanted_resolution_height, 32, SDL_OPENGL); } if(!screen){ std::string const sdl_error{SDL_GetError()}; throw std::runtime_error("Failed to create SDL_Screen: " + sdl_error); } screen_width = screen->w; screen_height = screen->h; } void init_glew(){ #if defined(TARGET_GLEW) if (glewInit() != GLEW_OK) { throw std::runtime_error("Failed to initialize GLEW"); } #endif } public: GenericMain(bool const fullscreen, int const wanted_resolution_width, int const wanted_resolution_height) : al_context() { init_sdl(fullscreen, wanted_resolution_width, wanted_resolution_height); init_glew(); } template void main(T... args){ std::shared_ptr game{new Game {screen_width, screen_height, game, args...}}; std::weak_ptr previous_game = game; bool done = false; Input input; // for calculation fps auto fps_time = SDL_GetTicks(); int frame_count_in_second = 0; auto now = SDL_GetTicks(); while (!done) { SDL_Event event; input.keys_went_down.clear(); input.keys_went_up.clear(); input.mouse.went_down.clear(); input.mouse.went_up.clear(); bool any_key_pressed = false; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: done = true; break; case SDL_KEYDOWN: { auto const& key = event.key.keysym.sym; input.keys_pressed[key] = true; input.keys_went_down[key] = true; if (key == SDLK_ESCAPE){ done = true; } } break; case SDL_KEYUP: { any_key_pressed = true; auto const& key = event.key.keysym.sym; input.keys_pressed[key] = false; input.keys_went_up[key] = true; break; } case SDL_MOUSEMOTION: { input.mouse.difference[0] = event.motion.x - input.mouse.position[0]; input.mouse.difference[1] = event.motion.y - input.mouse.position[1]; input.mouse.position[0] = event.motion.x; input.mouse.position[1] = event.motion.y; break; } case SDL_MOUSEBUTTONDOWN: { auto const b = Input::Mouse::button_from_sdl_button(event.button.button); input.mouse.is_pressed[b] = true; input.mouse.went_down[b] = true; input.mouse.position[0] = event.button.x; input.mouse.position[1] = event.button.y; break; } case SDL_MOUSEBUTTONUP: { auto const b = Input::Mouse::button_from_sdl_button(event.button.button); input.mouse.is_pressed[b] = false; input.mouse.went_up[b] = true; input.mouse.position[0] = event.button.x; input.mouse.position[1] = event.button.y; break; } default: break; } } if(any_key_pressed && game->has_ended()){ game.reset(new Game {screen_width, screen_height, game, args...}); } if(previous_game.expired()){ previous_game = game; now = SDL_GetTicks(); } float const dt = (SDL_GetTicks() - now)/1000.0f; now = SDL_GetTicks(); game->update(dt, input); game->draw(); SDL_GL_SwapBuffers(); ++frame_count_in_second; // one second has past if(SDL_GetTicks() - fps_time > 30.0f * 1000.0f){ fps_time = SDL_GetTicks(); COUT << "Average FPS: " << frame_count_in_second/30.0f << std::endl; frame_count_in_second = 0; } input.mouse.difference = moggle::vector2{0,0}; } } };