bettola/src/bettola.cpp

163 lines
4.5 KiB
C++

#include <GL/glew.h>
/* FINE LSP!! I'll play your games!!!! */
#include <SDL3/SDL_events.h> /* ~HJAPPY?!?!?! */
#include <SDL3/SDL_mouse.h>
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_timer.h>
#include <SDL3/SDL_video.h>
#include <cstdlib>
#include <cstdio>
#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;
}