#include /* FINE LSP!! I'll play your games!!!! */ #include /* ~HJAPPY?!?!?! */ #include #include #include #include #include #include #include "game/player.h" #include "graphics/camera.h" #include "bettola.h" /* Dacav's resolution ;) */ const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 600; Bettola::Bettola(void) : _is_running(false), _window(nullptr), _gl_context(nullptr), _camera_mode(Camera::CameraMode::FIRST_PERSON) {} Bettola::~Bettola(void) { if(_gl_context) { SDL_GL_DestroyContext(_gl_context); } if(_window) { SDL_DestroyWindow(_window); } SDL_Quit(); } bool Bettola::init_sdl(void) { if(!SDL_Init(SDL_INIT_VIDEO)) { fprintf(stderr, "Failed to init SDL! SDL ERROR: %s\n", SDL_GetError()); return false; } return true; } int Bettola::run(void) { if(!init_sdl()) return -1; if(!create_window()) return -1; if(!create_gl_context()) return -1; if(!_game_client.connect("127.0.0.1", 12345)) { return -1; } if(!_renderer.init(SCREEN_WIDTH, SCREEN_HEIGHT)) { return -1; } _is_running = true; Uint64 perf_freq = SDL_GetPerformanceFrequency(); Uint64 last_count = SDL_GetPerformanceCounter(); double delta_time = 0; while(_is_running) { Uint64 current_counter = SDL_GetPerformanceCounter(); delta_time = (double)(current_counter-last_count) / (double)perf_freq; last_count = current_counter; process_events(); update(delta_time); render(); } return 0; } void Bettola::process_events(void) { SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type == SDL_EVENT_QUIT) { _is_running = false; } else if(event.type == SDL_EVENT_MOUSE_MOTION) { /* Y is inverted. */ _camera.process_mouse_movement((float)event.motion.xrel, (float)-event.motion.yrel); } else if(event.type == SDL_EVENT_MOUSE_WHEEL) { _camera.process_mouse_scroll((float)event.wheel.y); } else if(event.type == SDL_EVENT_KEY_DOWN) { switch(event.key.key) { case SDLK_W: _input.up = true; break; case SDLK_S: _input.down = true; break; case SDLK_A: _input.left = true; break; case SDLK_D: _input.right = true; break; case SDLK_V: _camera_mode = (_camera_mode == Camera::CameraMode::FIRST_PERSON) ? Camera::CameraMode::THIRD_PERSON :Camera::CameraMode::FIRST_PERSON; break; } } else if(event.type == SDL_EVENT_KEY_UP) { switch(event.key.key) { case SDLK_W: _input.up = false; break; case SDLK_S: _input.down = false; break; case SDLK_A: _input.left = false; break; case SDLK_D: _input.right = false; break; } } } } void Bettola::update(double dt) { /* Get a mutable reference to the local player. */ Player& player = _game_client.get_player_for_write(); /* Set local player's velocity based on input and cam direction. */ player.set_velocity_direction(_input, _camera.get_front()); /* Process network messages and send input to the server. */ _game_client.process_network_messages(); _game_client.send_input(_input, _camera, dt); /* Update all players (local prediction and remote interpolation). */ _game_client.update_players(dt); /* Update camera to follow the local player. */ const BettolaMath::Vec3 player_pos = player.get_position(); _camera.update(player_pos, _camera_mode); } void Bettola::render(void) { _renderer.render(_camera, _game_client.get_player(), _game_client.get_remote_players(), _game_client.get_world()); SDL_GL_SwapWindow(_window); } bool Bettola::create_window(void) { 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); /* Don't you dare f.ckin fail to open!!!!! */ _window = SDL_CreateWindow("Bettola Makes No Sense!", SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL); if(!_window) { fprintf(stderr, "Failed to create window! SDL_ERROR: %s\n", SDL_GetError()); return false; } /* Capture mouse cursor. */ SDL_SetWindowRelativeMouseMode(_window, true); return true; } bool Bettola::create_gl_context(void) { _gl_context = SDL_GL_CreateContext(_window); if(!_gl_context) { fprintf(stderr, "Failed to create OpenGL context! SDL_ERROR: %s\n", SDL_GetError()); return false; } return true; }