1
Fork 0
This repository has been archived on 2025-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
beats-motor-client/src/generic_main.hpp
2013-04-16 15:29:55 +02:00

179 lines
4.4 KiB
C++

#include <iostream>
#include <memory>
#include <map>
#include <SDL/SDL.h>
#include <moggle/core/gl.hpp>
#include <motor/sound/sound.hpp>
#include "Base.hpp"
#ifndef __unused
#define __unused __attribute__((unused))
#endif
std::map<void*, std::string> mysterious_pointers;
#include <motor/sound/sound.hpp>
unsigned int motor::al::Buffer::nr_buffers = 0;
unsigned int motor::al::Source::nr_sources = 0;
template <typename Game>
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 <typename... T>
void main(T... args){
std::shared_ptr<games::Base> game{new Game {screen_width, screen_height, game, args...}};
std::weak_ptr<games::Base> 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<float>{0,0};
}
}
};