ref: 3c6de42ce452499062773d64d393aff8bee42a30
dir: /src/platform_sdl.c/
#include <SDL2/SDL.h> #include "platform.h" #include "input.h" #include "system.h" static uint64_t perf_freq = 0; static bool wants_to_exit = false; static SDL_Window *window; static SDL_AudioDeviceID audio_device; static void (*audio_callback)(float *buffer, uint32_t len) = NULL; void platform_exit() { wants_to_exit = true; } void platform_pump_events(void) { SDL_Event ev; while (SDL_PollEvent(&ev)) { // Input Keyboard if (ev.type == SDL_KEYDOWN || ev.type == SDL_KEYUP) { int code = ev.key.keysym.scancode; float state = ev.type == SDL_KEYDOWN ? 1.0 : 0.0; if (code >= SDL_SCANCODE_LCTRL && code <= SDL_SCANCODE_RALT) { int code_internal = code - SDL_SCANCODE_LCTRL + INPUT_KEY_LCTRL; input_set_button_state(code_internal, state); } else if (code > 0 && code < INPUT_KEY_MAX) { input_set_button_state(code, state); } } else if (ev.type == SDL_TEXTINPUT) { input_textinput(ev.text.text[0]); } // Mouse buttons else if ( ev.type == SDL_MOUSEBUTTONDOWN || ev.type == SDL_MOUSEBUTTONUP ) { button_t button = INPUT_BUTTON_NONE; switch (ev.button.button) { case SDL_BUTTON_LEFT: button = INPUT_MOUSE_LEFT; break; case SDL_BUTTON_MIDDLE: button = INPUT_MOUSE_MIDDLE; break; case SDL_BUTTON_RIGHT: button = INPUT_MOUSE_RIGHT; break; default: break; } if (button != INPUT_BUTTON_NONE) { float state = ev.type == SDL_MOUSEBUTTONDOWN ? 1.0 : 0.0; input_set_button_state(button, state); } } // Mouse wheel else if (ev.type == SDL_MOUSEWHEEL) { button_t button = ev.wheel.y > 0 ? INPUT_MOUSE_WHEEL_UP : INPUT_MOUSE_WHEEL_DOWN; input_set_button_state(button, 1.0); input_set_button_state(button, 0.0); } // Mouse move else if (ev.type == SDL_MOUSEMOTION) { input_set_mouse_pos(ev.motion.x, ev.motion.y); } // Window Events if (ev.type == SDL_QUIT) { wants_to_exit = true; } else if ( ev.type == SDL_WINDOWEVENT && ( ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED || ev.window.event == SDL_WINDOWEVENT_RESIZED ) ) { system_resize(platform_screen_size()); } } } double platform_now() { uint64_t perf_counter = SDL_GetPerformanceCounter(); return (double)perf_counter / (double)perf_freq; } void platform_set_fullscreen(bool fullscreen) { if (fullscreen) { int32_t display = SDL_GetWindowDisplayIndex(window); SDL_DisplayMode mode; SDL_GetDesktopDisplayMode(display, &mode); //SDL_SetWindowDisplayMode(window, &mode); //SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); SDL_ShowCursor(SDL_DISABLE); } else { SDL_SetWindowFullscreen(window, 0); SDL_ShowCursor(SDL_ENABLE); } } void platform_audio_callback(void* userdata, uint8_t* stream, int len) { if (audio_callback) { audio_callback((float *)stream, len/sizeof(float)); } else { memset(stream, 0, len); } } void platform_set_audio_mix_cb(void (*cb)(float *buffer, uint32_t len)) { audio_callback = cb; SDL_PauseAudioDevice(audio_device, 0); } #if defined(RENDERER_GL) // ---------------------------------------------------- #define PLATFORM_WINDOW_FLAGS SDL_WINDOW_OPENGL SDL_GLContext platform_gl; void platform_video_init() { #if defined(USE_GLES2) SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); #endif platform_gl = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(1); } void platform_prepare_frame() { // nothing } void platform_video_cleanup() { SDL_GL_DeleteContext(platform_gl); } void platform_end_frame() { SDL_GL_SwapWindow(window); } vec2i_t platform_screen_size() { int width, height; SDL_GL_GetDrawableSize(window, &width, &height); return vec2i(width, height); } #elif defined(RENDERER_SOFTWARE) // ---------------------------------------------- #define PLATFORM_WINDOW_FLAGS 0 static SDL_Renderer *renderer; static SDL_Texture *screenbuffer = NULL; static void *screenbuffer_pixels = NULL; static int screenbuffer_pitch; static vec2i_t screenbuffer_size; static vec2i_t screen_size; void platform_video_init(void) { screenbuffer_size = vec2i(0, 0); screen_size = vec2i(0, 0); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); } void platform_video_cleanup(void) { } void platform_prepare_frame(void) { if (screen_size.x != screenbuffer_size.x || screen_size.y != screenbuffer_size.y) { if (screenbuffer) { SDL_DestroyTexture(screenbuffer); } screenbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, screen_size.x, screen_size.y); screenbuffer_size = screen_size; } SDL_LockTexture(screenbuffer, NULL, &screenbuffer_pixels, &screenbuffer_pitch); } void platform_end_frame(void) { screenbuffer_pixels = NULL; SDL_UnlockTexture(screenbuffer); SDL_RenderCopy(renderer, screenbuffer, NULL, NULL); SDL_RenderPresent(renderer); } rgba_t *platform_get_screenbuffer(int32_t *pitch) { *pitch = screenbuffer_pitch; return screenbuffer_pixels; } vec2i_t platform_screen_size(void) { int width, height; SDL_GetWindowSize(window, &width, &height); // float aspect = (float)width / (float)height; // screen_size = vec2i(240 * aspect, 240); screen_size = vec2i(width, height); return screen_size; } #else #error "Unsupported renderer for platform SDL" #endif void global_init(void); int main(int argc, char *argv[]) { global_init(); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK); SDL_AudioSpec spec = { .freq = 44100, .format = AUDIO_F32, .channels = 2, .samples = 1024, .callback = platform_audio_callback }; audio_device = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0); perf_freq = SDL_GetPerformanceFrequency(); window = SDL_CreateWindow( SYSTEM_WINDOW_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SYSTEM_WINDOW_WIDTH, SYSTEM_WINDOW_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | PLATFORM_WINDOW_FLAGS | SDL_WINDOW_ALLOW_HIGHDPI ); platform_video_init(); system_init(); while (!wants_to_exit) { platform_pump_events(); platform_prepare_frame(); system_update(); platform_end_frame(); } system_cleanup(); platform_video_cleanup(); SDL_CloseAudioDevice(audio_device); SDL_Quit(); return 0; }