shithub: wipeout

ref: 5fcf2feec81e753d0188bb10da9db0a5ee061957
dir: /src/platform_sokol.c/

View raw version
#include "platform.h"
#include "system.h"

#if defined(RENDERER_GL)
	#ifdef __EMSCRIPTEN__
		#define SOKOL_GLES2
	#else
		#define SOKOL_GLCORE33
	#endif
#else
	#error "Unsupported renderer for platform SOKOL"
#endif

#define SOKOL_IMPL
#include "libs/sokol_audio.h"
#include "libs/sokol_time.h"
#include "libs/sokol_app.h"
#include "input.h"

static const uint8_t keyboard_map[] = {
	[SAPP_KEYCODE_SPACE] = INPUT_KEY_SPACE,
	[SAPP_KEYCODE_APOSTROPHE] = INPUT_KEY_APOSTROPHE,
	[SAPP_KEYCODE_COMMA] = INPUT_KEY_COMMA,
	[SAPP_KEYCODE_MINUS] = INPUT_KEY_MINUS,
	[SAPP_KEYCODE_PERIOD] = INPUT_KEY_PERIOD,
	[SAPP_KEYCODE_SLASH] = INPUT_KEY_SLASH,
	[SAPP_KEYCODE_0] = INPUT_KEY_0,
	[SAPP_KEYCODE_1] = INPUT_KEY_1,
	[SAPP_KEYCODE_2] = INPUT_KEY_2,
	[SAPP_KEYCODE_3] = INPUT_KEY_3,
	[SAPP_KEYCODE_4] = INPUT_KEY_4,
	[SAPP_KEYCODE_5] = INPUT_KEY_5,
	[SAPP_KEYCODE_6] = INPUT_KEY_6,
	[SAPP_KEYCODE_7] = INPUT_KEY_7,
	[SAPP_KEYCODE_8] = INPUT_KEY_8,
	[SAPP_KEYCODE_9] = INPUT_KEY_9,
	[SAPP_KEYCODE_SEMICOLON] = INPUT_KEY_SEMICOLON,
	[SAPP_KEYCODE_EQUAL] = INPUT_KEY_EQUALS,
	[SAPP_KEYCODE_A] = INPUT_KEY_A,
	[SAPP_KEYCODE_B] = INPUT_KEY_B,
	[SAPP_KEYCODE_C] = INPUT_KEY_C,
	[SAPP_KEYCODE_D] = INPUT_KEY_D,
	[SAPP_KEYCODE_E] = INPUT_KEY_E,
	[SAPP_KEYCODE_F] = INPUT_KEY_F,
	[SAPP_KEYCODE_G] = INPUT_KEY_G,
	[SAPP_KEYCODE_H] = INPUT_KEY_H,
	[SAPP_KEYCODE_I] = INPUT_KEY_I,
	[SAPP_KEYCODE_J] = INPUT_KEY_J,
	[SAPP_KEYCODE_K] = INPUT_KEY_K,
	[SAPP_KEYCODE_L] = INPUT_KEY_L,
	[SAPP_KEYCODE_M] = INPUT_KEY_M,
	[SAPP_KEYCODE_N] = INPUT_KEY_N,
	[SAPP_KEYCODE_O] = INPUT_KEY_O,
	[SAPP_KEYCODE_P] = INPUT_KEY_P,
	[SAPP_KEYCODE_Q] = INPUT_KEY_Q,
	[SAPP_KEYCODE_R] = INPUT_KEY_R,
	[SAPP_KEYCODE_S] = INPUT_KEY_S,
	[SAPP_KEYCODE_T] = INPUT_KEY_T,
	[SAPP_KEYCODE_U] = INPUT_KEY_U,
	[SAPP_KEYCODE_V] = INPUT_KEY_V,
	[SAPP_KEYCODE_W] = INPUT_KEY_W,
	[SAPP_KEYCODE_X] = INPUT_KEY_X,
	[SAPP_KEYCODE_Y] = INPUT_KEY_Y,
	[SAPP_KEYCODE_Z] = INPUT_KEY_Z,
	[SAPP_KEYCODE_LEFT_BRACKET] = INPUT_KEY_LEFTBRACKET,
	[SAPP_KEYCODE_BACKSLASH] = INPUT_KEY_BACKSLASH,
	[SAPP_KEYCODE_RIGHT_BRACKET] = INPUT_KEY_RIGHTBRACKET,
	[SAPP_KEYCODE_GRAVE_ACCENT] = INPUT_KEY_TILDE,
	[SAPP_KEYCODE_WORLD_1] = INPUT_INVALID,				// not implemented
	[SAPP_KEYCODE_WORLD_2] = INPUT_INVALID,				// not implemented
	[SAPP_KEYCODE_ESCAPE] = INPUT_KEY_ESCAPE,
	[SAPP_KEYCODE_ENTER] = INPUT_KEY_RETURN,
	[SAPP_KEYCODE_TAB] = INPUT_KEY_TAB,
	[SAPP_KEYCODE_BACKSPACE] = INPUT_KEY_BACKSPACE,
	[SAPP_KEYCODE_INSERT] = INPUT_KEY_INSERT,
	[SAPP_KEYCODE_DELETE] = INPUT_KEY_DELETE,
	[SAPP_KEYCODE_RIGHT] = INPUT_KEY_RIGHT,
	[SAPP_KEYCODE_LEFT] = INPUT_KEY_LEFT,
	[SAPP_KEYCODE_DOWN] = INPUT_KEY_DOWN,
	[SAPP_KEYCODE_UP] = INPUT_KEY_UP,
	[SAPP_KEYCODE_PAGE_UP] = INPUT_KEY_PAGEUP,
	[SAPP_KEYCODE_PAGE_DOWN] = INPUT_KEY_PAGEDOWN,
	[SAPP_KEYCODE_HOME] = INPUT_KEY_HOME,
	[SAPP_KEYCODE_END] = INPUT_KEY_END,
	[SAPP_KEYCODE_CAPS_LOCK] = INPUT_KEY_CAPSLOCK,
	[SAPP_KEYCODE_SCROLL_LOCK] = INPUT_KEY_SCROLLLOCK,
	[SAPP_KEYCODE_NUM_LOCK] = INPUT_KEY_NUMLOCK,
	[SAPP_KEYCODE_PRINT_SCREEN] = INPUT_KEY_PRINTSCREEN,
	[SAPP_KEYCODE_PAUSE] = INPUT_KEY_PAUSE,
	[SAPP_KEYCODE_F1] = INPUT_KEY_F1,
	[SAPP_KEYCODE_F2] = INPUT_KEY_F2,
	[SAPP_KEYCODE_F3] = INPUT_KEY_F3,
	[SAPP_KEYCODE_F4] = INPUT_KEY_F4,
	[SAPP_KEYCODE_F5] = INPUT_KEY_F5,
	[SAPP_KEYCODE_F6] = INPUT_KEY_F6,
	[SAPP_KEYCODE_F7] = INPUT_KEY_F7,
	[SAPP_KEYCODE_F8] = INPUT_KEY_F8,
	[SAPP_KEYCODE_F9] = INPUT_KEY_F9,
	[SAPP_KEYCODE_F10] = INPUT_KEY_F10,
	[SAPP_KEYCODE_F11] = INPUT_KEY_F11,
	[SAPP_KEYCODE_F12] = INPUT_KEY_F12,
	[SAPP_KEYCODE_F13] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F14] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F15] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F16] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F17] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F18] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F19] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F20] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F21] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F22] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F23] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F24] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_F25] = INPUT_INVALID, 				// not implemented
	[SAPP_KEYCODE_KP_0] = INPUT_KEY_KP_0,
	[SAPP_KEYCODE_KP_1] = INPUT_KEY_KP_1,
	[SAPP_KEYCODE_KP_2] = INPUT_KEY_KP_2,
	[SAPP_KEYCODE_KP_3] = INPUT_KEY_KP_3,
	[SAPP_KEYCODE_KP_4] = INPUT_KEY_KP_4,
	[SAPP_KEYCODE_KP_5] = INPUT_KEY_KP_5,
	[SAPP_KEYCODE_KP_6] = INPUT_KEY_KP_6,
	[SAPP_KEYCODE_KP_7] = INPUT_KEY_KP_7,
	[SAPP_KEYCODE_KP_8] = INPUT_KEY_KP_8,
	[SAPP_KEYCODE_KP_9] = INPUT_KEY_KP_9,
	[SAPP_KEYCODE_KP_DECIMAL] = INPUT_KEY_KP_PERIOD,
	[SAPP_KEYCODE_KP_DIVIDE] = INPUT_KEY_KP_DIVIDE,
	[SAPP_KEYCODE_KP_MULTIPLY] = INPUT_KEY_KP_MULTIPLY,
	[SAPP_KEYCODE_KP_SUBTRACT] = INPUT_KEY_KP_MINUS,
	[SAPP_KEYCODE_KP_ADD] = INPUT_KEY_KP_PLUS,
	[SAPP_KEYCODE_KP_ENTER] = INPUT_KEY_KP_ENTER,
	[SAPP_KEYCODE_KP_EQUAL] = INPUT_INVALID, 			// not implemented
	[SAPP_KEYCODE_LEFT_SHIFT] = INPUT_KEY_LSHIFT,
	[SAPP_KEYCODE_LEFT_CONTROL] = INPUT_KEY_LCTRL,
	[SAPP_KEYCODE_LEFT_ALT] = INPUT_KEY_LALT,
	[SAPP_KEYCODE_LEFT_SUPER] = INPUT_INVALID, 			// not implemented
	[SAPP_KEYCODE_RIGHT_SHIFT] = INPUT_KEY_RSHIFT,
	[SAPP_KEYCODE_RIGHT_CONTROL] = INPUT_KEY_RCTRL,
	[SAPP_KEYCODE_RIGHT_ALT] = INPUT_KEY_RALT,
	[SAPP_KEYCODE_RIGHT_SUPER] = INPUT_INVALID, 		// not implemented
	[SAPP_KEYCODE_MENU] = INPUT_INVALID, 				// not implemented
};


static void (*audio_callback)(float *buffer, uint32_t len) = NULL;

void platform_exit() {
	sapp_quit();
}

vec2i_t platform_screen_size() {
	return vec2i(sapp_width(), sapp_height());
}

double platform_now() {
	return stm_sec(stm_now());
}

void platform_set_fullscreen(bool fullscreen) {
	if (fullscreen == sapp_is_fullscreen()) {
		return;
	}

	sapp_toggle_fullscreen();
}

void platform_handle_event(const sapp_event* ev) {
	// Input Keyboard
	if (ev->type == SAPP_EVENTTYPE_KEY_DOWN || ev->type == SAPP_EVENTTYPE_KEY_UP) {
		float state = ev->type == SAPP_EVENTTYPE_KEY_DOWN ? 1.0 : 0.0;
		if (ev->key_code > 0 && ev->key_code < sizeof(keyboard_map)) {
			int code = keyboard_map[ev->key_code];
			input_set_button_state(code, state);
		}
	}

	else if (ev->type == SAPP_EVENTTYPE_CHAR) {
		input_textinput(ev->char_code);
	}


	// Input Gamepad Axis
	// TODO: not implemented by sokol_app itself

	// Mouse buttons
	else if (
		ev->type == SAPP_EVENTTYPE_MOUSE_DOWN ||
		ev->type == SAPP_EVENTTYPE_MOUSE_UP
	) {
		button_t button = INPUT_BUTTON_NONE;
		switch (ev->mouse_button) {
			case SAPP_MOUSEBUTTON_LEFT: button = INPUT_MOUSE_LEFT; break;
			case SAPP_MOUSEBUTTON_MIDDLE: button = INPUT_MOUSE_MIDDLE; break;
			case SAPP_MOUSEBUTTON_RIGHT: button = INPUT_MOUSE_RIGHT; break;
			default: break;
		}
		if (button != INPUT_BUTTON_NONE) {
			float state = ev->type == SAPP_EVENTTYPE_MOUSE_DOWN ? 1.0 : 0.0;
			input_set_button_state(button, state);
		}
	}

	// Mouse wheel
	else if (ev->type == SAPP_EVENTTYPE_MOUSE_SCROLL) {
		button_t button = ev->scroll_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 == SAPP_EVENTTYPE_MOUSE_MOVE) {
		input_set_mouse_pos(ev->mouse_x, ev->mouse_y);
	}

	// Window Events
	if (ev->type == SAPP_EVENTTYPE_RESIZED) {
		system_resize(vec2i(ev->window_width, ev->window_height));
	}
}

void platform_audio_callback(float* buffer, int num_frames, int num_channels) {
	if (audio_callback) {
		audio_callback(buffer, num_frames * num_channels);
	}
	else {
		memset(buffer, 0, num_frames * sizeof(float));
	}
}

void platform_set_audio_mix_cb(void (*cb)(float *buffer, uint32_t len)) {
	audio_callback = cb;
}

sapp_desc sokol_main(int argc, char* argv[]) {
	stm_setup();

	saudio_setup(&(saudio_desc){
		.sample_rate = 44100,
		.buffer_frames = 4096,
		.num_packets = 256,
		.num_channels = 2,
		.stream_cb = platform_audio_callback,
	});

	return (sapp_desc) {
		.width = SYSTEM_WINDOW_WIDTH,
		.height = SYSTEM_WINDOW_HEIGHT,
		.init_cb = system_init,
		.frame_cb = system_update,
		.cleanup_cb = system_cleanup,
		.event_cb = platform_handle_event,
		.win32_console_attach = true
	};
}