#include "GL/glew.h" #include "SDL2/SDL.h" #include "prge.h" #include "game.h" #include "game.c" void process_mouse_pos(Input *input, S32 x, S32 y) { V2 pos = v2((F32)x, (F32)y); if (input->first_mouse) { input->mouse_pos = pos; input->first_mouse = 0; } input->last_mouse_pos = input->mouse_pos; input->mouse_pos = pos; input->mouse_offset = v2sub(input->mouse_pos, input->last_mouse_pos); } void process_window_resize() { } void process_key(U8 state, Key *key) { key->state = (state == SDL_PRESSED) ? KeyState_PRESS : KeyState_RELEASE; } void process_keyboard(Input *input, SDL_KeyboardEvent *key) { switch (key->keysym.scancode) { case SDL_SCANCODE_D: process_key(key->state, &input->move_right); break; case SDL_SCANCODE_W: process_key(key->state, &input->move_forward); break; case SDL_SCANCODE_A: process_key(key->state, &input->move_left); break; case SDL_SCANCODE_S: process_key(key->state, &input->move_backward); break; case SDL_SCANCODE_E: process_key(key->state, &input->move_up); break; case SDL_SCANCODE_Q: process_key(key->state, &input->move_down); break; case SDL_SCANCODE_SPACE: process_key(key->state, &input->jump); break; case SDL_SCANCODE_RIGHT: process_key(key->state, &input->action_right); break; case SDL_SCANCODE_UP: process_key(key->state, &input->action_up); break; case SDL_SCANCODE_LEFT: process_key(key->state, &input->action_left); break; case SDL_SCANCODE_DOWN: process_key(key->state, &input->action_down); break; case SDL_SCANCODE_ESCAPE: process_key(key->state, &input->exit); break; default: break; } } void handle_events(Input *input) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: case SDL_KEYUP: process_keyboard(input, &event.key); break; case SDL_MOUSEMOTION: process_mouse_pos(input, event.motion.x, event.motion.y); break; case SDL_WINDOWEVENT_RESIZED: process_window_resize(); break; default: break; } } } F32 get_elapsed_seconds(U64 cur, U64 last) { F32 result = ((F32)cur-(F32)last)/1000.0f; return result; } F32 lock_framerate(U64 last, F32 target) { F32 target_mspf = 1000.0f/target; F32 elapsed = get_elapsed_seconds(SDL_GetTicks64(), last)*1000.0f; if (elapsed < target_mspf) { /* F32 sleep = target_mspf-elapsed-1.0f; */ F32 sleep = target_mspf-elapsed; if (sleep > 0.0f) SDL_Delay(sleep); /* do { elapsed = get_elapsed_seconds(SDL_GetTicks64(), last)*1000.0f; } while (elapsed < target_mspf); */ } F32 dt = get_elapsed_seconds(SDL_GetTicks64(), last); return dt; } B32 sdl_init(S32 width, S32 height, SDL_Window **window, SDL_GLContext **context) { if (SDL_Init(SDL_INIT_VIDEO)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } 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); U32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; (*window) = SDL_CreateWindow("prge game example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, flags); if (!(*window)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } (*context) = SDL_GL_CreateContext((*window)); if (!(*context)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } GLenum error = glewInit(); if (error != GLEW_OK) { SDL_Log("[ERROR] : GLEW : %s\n", glewGetErrorString(error)); return 0; } return 1; } int main(void) { /* NOTE(pryazha): Engine init */ Input input = input_init(); S32 width = 800, height = 600; /* NOTE(pryazha): SDL init */ SDL_Window *window; SDL_GLContext *context; if (!sdl_init(width, height, &window, &context)) { SDL_Quit(); return 1; } /* NOTE(pryazha): Game init */ State state = {0}; game_init(&state); U64 last = SDL_GetTicks64(); while (input.is_running) { handle_events(&input); input.dt = lock_framerate(last, 60.0f); last = SDL_GetTicks64(); game_update_and_render(&state, &input); input_update(&input); SDL_GL_SwapWindow(window); } game_clear(&state); SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); SDL_Quit(); return 0; }