#include "GL/glew.h" #include "SDL3/SDL.h" #include "prge.h" #include "game.h" #include "game.c" void process_mouse_pos(Input *input, SDL_MouseMotionEvent *mouseev) { V2 offset; input->mouse_pos = v2((F32)mouseev->x, (F32)mouseev->y); if (input->first_mouse) input->first_mouse = 0; offset = v2((F32)mouseev->xrel, (F32)mouseev->yrel); input->mouse_offset = v2add(input->mouse_offset, offset); } void process_key(B32 down, Key *key) { key->state = (down ? KeyState_PRESS : KeyState_RELEASE); } void process_keyboard(Input *input, SDL_KeyboardEvent *keyev) { switch (keyev->scancode) { case SDL_SCANCODE_D: process_key(keyev->down, &input->move_right); break; case SDL_SCANCODE_W: process_key(keyev->down, &input->move_forward); break; case SDL_SCANCODE_A: process_key(keyev->down, &input->move_left); break; case SDL_SCANCODE_S: process_key(keyev->down, &input->move_backward); break; case SDL_SCANCODE_E: process_key(keyev->down, &input->move_up); break; case SDL_SCANCODE_Q: process_key(keyev->down, &input->move_down); break; case SDL_SCANCODE_SPACE: process_key(keyev->down, &input->jump); break; case SDL_SCANCODE_RIGHT: process_key(keyev->down, &input->action_right); break; case SDL_SCANCODE_UP: process_key(keyev->down, &input->action_up); break; case SDL_SCANCODE_LEFT: process_key(keyev->down, &input->action_left); break; case SDL_SCANCODE_DOWN: process_key(keyev->down, &input->action_down); break; case SDL_SCANCODE_ESCAPE: process_key(keyev->down, &input->exit); break; default: break; } } void process_mouse_buttons(Input *input, SDL_MouseButtonEvent *buttonev) { if (buttonev->button == SDL_BUTTON_LEFT) process_key(buttonev->down, &input->mouse_left); else if (buttonev->button == SDL_BUTTON_RIGHT) process_key(buttonev->down, &input->mouse_right); } void handle_events(Window *wnd, Input *input) { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: process_keyboard(input, &event.key); break; case SDL_EVENT_MOUSE_MOTION: process_mouse_pos(input, &event.motion); break; case SDL_EVENT_MOUSE_BUTTON_DOWN: case SDL_EVENT_MOUSE_BUTTON_UP: process_mouse_buttons(input, &event.button); break; case SDL_EVENT_WINDOW_RESIZED: wnd->width = event.window.data1; wnd->height = event.window.data2; break; default: break; } } } F32 get_elapsed_seconds(U64 cur, U64 last) { F32 res; res = ((F32)cur-(F32)last)/1000.0f; return res; } F32 lock_framerate(U64 last, F32 target) { F32 target_mspf, elapsed, sleep, dt; elapsed = get_elapsed_seconds(SDL_GetTicks(), last)*1000.0f; target_mspf = 1000.0f/target; if (elapsed < target_mspf) { sleep = target_mspf-elapsed; if (sleep > 0.0f) SDL_Delay(sleep); /* do { elapsed = get_elapsed_seconds(SDL_GetTicks(), last)*1000.0f; } while (elapsed < target_mspf); */ } dt = get_elapsed_seconds(SDL_GetTicks(), last); return dt; } B32 sdl_init(Window *wnd, SDL_Window **sdl_window, SDL_GLContext *context) { U32 flags; GLenum error; Arena *tmpar; char *wname; 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); tmpar = arena_alloc(0); wname = str8tocstr(tmpar, wnd->name); flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; (*sdl_window) = SDL_CreateWindow(wname, wnd->width, wnd->height, flags); arena_release(tmpar); if (!(*sdl_window)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } SDL_GetWindowSize(*sdl_window, &wnd->width, &wnd->height); (*context) = SDL_GL_CreateContext((*sdl_window)); if (!(*context)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } 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; Window wnd; input = input_init(); wnd = window_init(800, 600, str8lit("PRGE example")); /* NOTE(pryazha): SDL and OpenGL init */ SDL_Window *sdl_window; SDL_GLContext context; U64 last; if (!sdl_init(&wnd, &sdl_window, &context)) { SDL_Quit(); return 1; } glEnable(GL_DEPTH_TEST); /* NOTE(pryazha): Game init */ State state; MemoryZero(&state, sizeof(State)); init(&state); last = SDL_GetTicks(); while (input.is_running) { SDL_SetWindowRelativeMouseMode(sdl_window, input.capture_mouse); handle_events(&wnd, &input); input.dt = lock_framerate(last, 60.0f); last = SDL_GetTicks(); update_and_render(&wnd, &state, &input); input_update(&input); SDL_GL_SwapWindow(sdl_window); } clear(&state); SDL_GL_DestroyContext(context); SDL_DestroyWindow(sdl_window); SDL_Quit(); return 0; }