master uint/magnolia / source / platform / platform_sdl.c
  1#include <SDL2/SDL.h>
  2
  3#include "util.h"
  4#include "platform/platform.h"
  5
  6static void platform_key_set(MGContext* ctx, MGKey key, i32 down);
  7
  8/* set the state of a logical key */
  9static void platform_key_set(MGContext* ctx, MGKey key, i32 down)
 10{
 11	int i;
 12
 13	if (key == MGK_UNKNOWN)
 14		return;
 15
 16	for (i = 0; i < MG_KEYS_DOWN_MAX; i++) {
 17		if (ctx->keys[i] == key) {
 18			if (!down)
 19				ctx->keys[i] = MGK_UNKNOWN;
 20			return;
 21		}
 22	}
 23
 24	if (!down)
 25		return;
 26
 27	for (i = 0; i < MG_KEYS_DOWN_MAX; i++) {
 28		if (ctx->keys[i] == MGK_UNKNOWN) {
 29			ctx->keys[i] = key;
 30			return;
 31		}
 32	}
 33}
 34
 35void platform_get_drawable_size(MGContext* ctx, i32* width, i32* height)
 36{
 37#ifdef MG_RENDERER_SMALL3DLIB
 38	SDL_GetWindowSize(ctx->win, width, height);
 39#else
 40	SDL_GL_GetDrawableSize(ctx->win, width, height);
 41#endif
 42}
 43
 44void platform_get_mouse_state(i32* x, i32* y)
 45{
 46	SDL_GetRelativeMouseState(x, y);
 47}
 48
 49u64 platform_get_ticks(void)
 50{
 51	return SDL_GetTicks64();
 52}
 53
 54void platform_init(MGContext* ctx)
 55{
 56	int i;
 57
 58	for (i = 0; i < MG_KEYS_DOWN_MAX; i++)
 59		ctx->keys[i] = MGK_UNKNOWN;
 60
 61	if (SDL_Init(SDL_INIT_VIDEO) != 0)
 62		mg_die(MG_EC_SDL_INIT, "SDL_Init failed: %s", SDL_GetError());
 63
 64#ifdef MG_RENDERER_SOKOL
 65	/* TODO: OpenGL specifics */
 66	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 67	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
 68	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
 69	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 70	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 71#endif
 72}
 73
 74i32 platform_poll(MGContext* ctx)
 75{
 76	SDL_Event ev;
 77
 78	while (SDL_PollEvent(&ev)) {
 79		switch (ev.type) {
 80		case SDL_QUIT:
 81			return 0;
 82
 83		case SDL_KEYDOWN:
 84		case SDL_KEYUP:
 85			platform_key_set(ctx, ev.key.keysym.sym, ev.type == SDL_KEYDOWN);
 86			break;
 87
 88		case SDL_WINDOWEVENT:
 89			if (ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
 90				ctx->width = ev.window.data1;
 91				ctx->height = ev.window.data2;
 92			}
 93		}
 94	}
 95
 96	return 1;
 97}
 98
 99i32 platform_key_down(MGContext* ctx, MGKey key)
100{
101	int i;
102
103	if (!ctx || key == MGK_UNKNOWN)
104		return 0;
105
106	for (i = 0; i < MG_KEYS_DOWN_MAX; i++) {
107		if (ctx->keys[i] == key)
108			return 1;
109	}
110
111	return 0;
112}
113
114void platform_present(MGContext* ctx)
115{
116#ifdef MG_RENDERER_SMALL3DLIB
117	SDL_RenderPresent(ctx->vbe.renderer);
118#else
119	SDL_GL_SwapWindow(ctx->win);
120#endif
121}
122
123void platform_set_mouse_relative(i8 enabled)
124{
125	SDL_SetRelativeMouseMode(enabled);
126}
127
128void platform_shutdown(MGContext* ctx)
129{
130	if (!ctx)
131		return;
132
133#ifdef MG_RENDERER_SMALL3DLIB
134	if (ctx->vbe.renderer) {
135		SDL_DestroyRenderer(ctx->vbe.renderer);
136		ctx->vbe.renderer = NULL;
137	}
138#endif
139
140#ifdef MG_RENDERER_SOKOL
141	if (ctx->vbe.gl) {
142		SDL_GL_DeleteContext(ctx->vbe.gl);
143		ctx->vbe.gl = NULL;
144	}
145#endif
146
147	if (ctx->win) {
148		SDL_DestroyWindow(ctx->win);
149		ctx->win = NULL;
150	}
151
152	SDL_Quit();
153}
154
155void platform_window_create(MGContext* ctx)
156{
157	u32 flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
158#ifdef MG_RENDERER_SOKOL
159	flags |= SDL_WINDOW_OPENGL;
160#endif
161
162	ctx->win = SDL_CreateWindow(ctx->title, ctx->x, ctx->y, ctx->width, ctx->height, flags);
163
164	if (!ctx->win)
165		mg_die(MG_EC_SDL_CREATE_WIN, "Failed to create window: %s", SDL_GetError());
166
167#ifdef MG_RENDERER_SMALL3DLIB
168	ctx->vbe.renderer = SDL_CreateRenderer(ctx->win, -1, SDL_RENDERER_ACCELERATED);
169	if (!ctx->vbe.renderer)
170		ctx->vbe.renderer = SDL_CreateRenderer(ctx->win, -1, SDL_RENDERER_SOFTWARE);
171	if (!ctx->vbe.renderer)
172		mg_die(MG_EC_SDL_CREATE_RENDERER, "Failed to create SDL renderer: %s", SDL_GetError());
173#endif
174
175#ifdef MG_RENDERER_SOKOL
176	ctx->vbe.gl = SDL_GL_CreateContext(ctx->win);
177	if (!ctx->vbe.gl)
178		mg_die(MG_EC_GL_CTX_CREATE, "Failed to initialise GL Context");
179
180	if (SDL_GL_MakeCurrent(ctx->win, ctx->vbe.gl) != 0)
181		mg_die(MG_EC_GL_CTX_ACTIVATE, "Failed to activate GL Context: %s", SDL_GetError());
182
183	SDL_GL_SetSwapInterval(1);
184#endif
185}
186
187void platform_wait(u32 ms)
188{
189	SDL_Delay(ms);
190}