diff --git a/compile_linux.sh b/compile_linux.sh
index 69f07cf..c8e10a9 100755
--- a/compile_linux.sh
+++ b/compile_linux.sh
@@ -62,11 +62,11 @@ ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/mesh_utils.cpp -o sfw/
 ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/texture.cpp -o sfw/render_core/texture.o
 ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/image.cpp -o sfw/render_core/image.o
 ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/render_state.cpp -o sfw/render_core/render_state.o
-ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input/keyboard.cpp -o sfw/render_core/input/keyboard.o
-ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input/input_event.cpp -o sfw/render_core/input/input_event.o
-ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input/input_map.cpp -o sfw/render_core/input/input_map.o
-ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input/input.cpp -o sfw/render_core/input/input.o
-ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input/shortcut.cpp -o sfw/render_core/input/shortcut.o
+ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/keyboard.cpp -o sfw/render_core/keyboard.o
+ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input_event.cpp -o sfw/render_core/input_event.o
+ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input_map.cpp -o sfw/render_core/input_map.o
+ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/input.cpp -o sfw/render_core/input.o
+ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_core/shortcut.cpp -o sfw/render_core/shortcut.o
 
 ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_objects/camera_3d.cpp -o sfw/render_objects/camera_3d.o
 ccache g++ -Wall -D_REENTRANT -g -Isfw -c sfw/render_objects/object_3d.cpp -o sfw/render_objects/object_3d.o
@@ -98,9 +98,9 @@ ccache g++ -Wall -lm -ldl -lpthread -lX11  -D_REENTRANT -g sfw/core/aabb.o sfw/c
                         sfw/render_core/application.o sfw/render_core/scene.o sfw/render_core/window.o \
                         sfw/render_core/shader.o sfw/render_core/material.o sfw/render_core/mesh.o \
                         sfw/render_core/mesh_utils.o sfw/render_core/texture.o \
-                        sfw/render_core/input/input_event.o sfw/render_core/input/input_map.o \
-                        sfw/render_core/input/input.o sfw/render_core/input/shortcut.o \
-                        sfw/render_core/input/keyboard.o \
+                        sfw/render_core/input_event.o sfw/render_core/input_map.o \
+                        sfw/render_core/input.o sfw/render_core/shortcut.o \
+                        sfw/render_core/keyboard.o \
                         sfw/render_objects/camera_3d.o sfw/render_objects/object_3d.o sfw/render_objects/mesh_instance_3d.o \
                         sfw/render_objects/object_2d.o \
                         sfw/render_objects/sprite.o sfw/render_objects/tile_map.o \
diff --git a/game_scene.cpp b/game_scene.cpp
index 1c6d843..fd17dfe 100644
--- a/game_scene.cpp
+++ b/game_scene.cpp
@@ -4,7 +4,7 @@
 
 #include "core/memory.h"
 #include "render_core/3rd_glad.h"
-#include "render_core/input/keyboard.h"
+#include "render_core/keyboard.h"
 #include "render_core/mesh_utils.h"
 
 void GameScene::input_event(const Ref<InputEvent> &event) {
diff --git a/sfw/render_core/application.cpp b/sfw/render_core/application.cpp
index 702a8c3..0661262 100644
--- a/sfw/render_core/application.cpp
+++ b/sfw/render_core/application.cpp
@@ -3,8 +3,8 @@
 #include "core/math_defs.h"
 
 #include "core/stime.h"
-#include "render_core/input/input.h"
-#include "render_core/input/input_map.h"
+#include "render_core/input.h"
+#include "render_core/input_map.h"
 #include "render_core/window.h"
 
 #include "core/pool_vector.h"
diff --git a/sfw/render_core/fwk_input.c b/sfw/render_core/fwk_input.c
deleted file mode 100644
index acaf69a..0000000
--- a/sfw/render_core/fwk_input.c
+++ /dev/null
@@ -1,762 +0,0 @@
-// input framework
-// - rlyeh, public domain
-//
-// multi-touch(emscripten) port based on code by @procedural (MIT-0 licensed)
-
-// gotta love linux
-#ifdef __linux
-#undef KEY_ESC
-#undef KEY_TICK
-#undef KEY_1
-#undef KEY_2
-#undef KEY_3
-#undef KEY_4
-#undef KEY_5
-#undef KEY_6
-#undef KEY_7
-#undef KEY_8
-#undef KEY_9
-#undef KEY_0
-#undef KEY_BS
-#undef KEY_TAB
-#undef KEY_Q
-#undef KEY_W
-#undef KEY_E
-#undef KEY_R
-#undef KEY_T
-#undef KEY_Y
-#undef KEY_U
-#undef KEY_I
-#undef KEY_O
-#undef KEY_P
-#undef KEY_CAPS
-#undef KEY_A
-#undef KEY_S
-#undef KEY_D
-#undef KEY_F
-#undef KEY_G
-#undef KEY_H
-#undef KEY_J
-#undef KEY_K
-#undef KEY_L
-#undef KEY_ENTER
-#undef KEY_LSHIFT
-#undef KEY_Z
-#undef KEY_X
-#undef KEY_C
-#undef KEY_V
-#undef KEY_B
-#undef KEY_N
-#undef KEY_M
-#undef KEY_RSHIFT
-#undef KEY_UP
-#undef KEY_LCTRL
-#undef KEY_LALT
-#undef KEY_SPACE
-#undef KEY_RALT
-#undef KEY_RCTRL
-#undef KEY_LEFT
-#undef KEY_DOWN
-#undef KEY_RIGHT
-#undef KEY_INS
-#undef KEY_HOME
-#undef KEY_PGUP
-#undef KEY_DEL
-#undef KEY_END
-#undef KEY_PGDN
-#undef KEY_LMETA
-#undef KEY_RMETA
-#undef KEY_MENU
-#undef KEY_PRINT
-#undef KEY_PAUSE
-#undef KEY_SCROLL
-#undef KEY_NUMLOCK
-#undef KEY_MINUS
-#undef KEY_EQUAL
-#undef KEY_LSQUARE
-#undef KEY_RSQUARE
-#undef KEY_SEMICOLON
-#undef KEY_QUOTE
-#undef KEY_HASH
-#undef KEY_BAR
-#undef KEY_COMMA
-#undef KEY_DOT
-#undef KEY_SLASH
-#undef KEY_F1
-#undef KEY_F2
-#undef KEY_F3
-#undef KEY_F4
-#undef KEY_F5
-#undef KEY_F6
-#undef KEY_F7
-#undef KEY_F8
-#undef KEY_F9
-#undef KEY_F10
-#undef KEY_F11
-#undef KEY_F12
-#undef KEY_PAD1
-#undef KEY_PAD2
-#undef KEY_PAD3
-#undef KEY_PAD4
-#undef KEY_PAD5
-#undef KEY_PAD6
-#undef KEY_PAD7
-#undef KEY_PAD8
-#undef KEY_PAD9
-#undef KEY_PAD0
-#undef KEY_PADADD
-#undef KEY_PADSUB
-#undef KEY_PADMUL
-#undef KEY_PADDIV
-#undef KEY_PADDOT
-#undef KEY_PADENTER
-#undef MOUSE_L
-#undef MOUSE_M
-#undef MOUSE_R
-#undef GAMEPAD_CONNECTED
-#undef GAMEPAD_A
-#undef GAMEPAD_B
-#undef GAMEPAD_X
-#undef GAMEPAD_Y
-#undef GAMEPAD_UP
-#undef GAMEPAD_DOWN
-#undef GAMEPAD_LEFT
-#undef GAMEPAD_RIGHT
-#undef GAMEPAD_MENU
-#undef GAMEPAD_START
-#undef GAMEPAD_LB
-#undef GAMEPAD_RB
-#undef GAMEPAD_LTHUMB
-#undef GAMEPAD_RTHUMB
-#undef WINDOW_BLUR
-#undef WINDOW_FOCUS
-#undef WINDOW_CLOSE
-#undef WINDOW_MINIMIZE
-#undef WINDOW_MAXIMIZE
-#undef WINDOW_FULLSCREEN
-#undef WINDOW_WINDOWED
-#undef GAMEPAD_LPAD
-#undef GAMEPAD_LPAD
-#undef GAMEPAD_LPADY
-#undef GAMEPAD_RPAD
-#undef GAMEPAD_RPAD
-#undef GAMEPAD_RPADY
-#undef GAMEPAD_LT
-#undef GAMEPAD_RT
-#undef GAMEPAD_BATTERY
-#undef MOUSE
-#undef MOUSE
-#undef MOUSE_Y
-#undef MOUSE_W
-#undef TOUCH_X1
-#undef TOUCH_Y1
-#undef TOUCH_X2
-#undef TOUCH_Y2
-#undef WINDOW_RESIZE
-#undef WINDOW_RESIZE
-#undef WINDOW_RESIZEY
-#undef WINDOW_ORIENTATION
-#undef WINDOW_BATTERY
-#undef GAMEPAD_GUID
-#undef GAMEPAD_NAME
-#endif
-
-static int controller_id = 0;
-static int controller_cycle[4] = {0};
-
-static struct controller_t {
-    const char* strings[2];
-    float floats[7+3+4+4];
-    char  bits[104+3+15+7];
-} controller[4] = {0}, frame[4][60] = {{0},{0},{0},{0}};
-
-static struct controller_t *input_logger(int position, int advance) {
-    int *cycle = &controller_cycle[controller_id];
-    position += (*cycle += advance);
-    position = position >= 0 ? position % 60 : 60-1 + ((position+1) % 60);
-    return &frame[controller_id][position];
-}
-
-void input_mappings(const char *filename) {
-#if !is(ems) // emscripten: no glfwUpdateGamepadMappings() available
-    char* mappings = vfs_read(filename);
-    if( mappings ) { glfwUpdateGamepadMappings(mappings); /*REALLOC(mappings, 0);*/ }
-#endif
-}
-
-void input_init() {
-    do_once {
-        input_mappings("gamecontrollerdb.txt");
-    }
-    #if 0 // deprecated
-    void input_update();
-    window_hook(input_update, NULL);
-    #endif
-}
-
-static int any_key = 0;
-int input_anykey() {
-    return any_key;
-}
-
-void input_update() {
-    struct controller_t *c = &controller[0]; // @fixme
-
-    char *bits = &c->bits[0];
-    float *floats = c->floats; floats -= GAMEPAD_LPADX;
-    const char **strings = c->strings; strings -= GAMEPAD_GUID;
-    float mouse_wheel_old = floats[MOUSE_W];
-
-    struct controller_t clear = {0};
-    *c = clear;
-    for( int i = 0; i < countof(c->strings); ++i ) c->strings[i] = "";
-
-    struct GLFWwindow *win = window_handle();
-    // glfwSetInputMode(win, GLFW_STICKY_MOUSE_BUTTONS, GLFW_TRUE);
-    double mx, my;
-    glfwGetCursorPos(win, &mx, &my);
-    floats[MOUSE_X] = mx;
-    floats[MOUSE_Y] = my;
-    struct nk_glfw* glfw = glfwGetWindowUserPointer(win); // from nuklear, because it is overriding glfwSetScrollCallback()
-    floats[MOUSE_W] = !glfw ? 0 : mouse_wheel_old + (float)glfw->scroll_bak.x + (float)glfw->scroll_bak.y;
-    glfw->scroll_bak.x = glfw->scroll_bak.y = 0;
-
-    // Dear Win32 users,
-    // - Touchpad cursor freezing when any key is being pressed?
-    // If using Alps/Elantech/Dell/Toshiba touchpad driver or similar, ensure to disable TouchGuard, TouchCheck, PalmTracking, etc.
-    // - Touchpad button not clicking when any key is being pressed?
-    // Change Touchpad settings on Windows10 from HighSentivity (default) to MostSensitivity.
-    // - Apparently, a sane solution is just to never bind FIRE/JUMP actions to LMB/RMB buttons, and bind actions to keys instead.
-    bits[MOUSE_L] = (glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
-    bits[MOUSE_M] = (glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
-    bits[MOUSE_R] = (glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
-
-    #define k2(VK,GLFW) [KEY_##VK] = GLFW_KEY_##GLFW
-    #define k(VK) k2(VK,VK)
-    int table[] = {
-        k2(ESC,ESCAPE),
-        k2(TICK,GRAVE_ACCENT), k(1),k(2),k(3),k(4),k(5),k(6),k(7),k(8),k(9),k(0), k2(BS,BACKSPACE),
-        k(TAB),                k(Q),k(W),k(E),k(R),k(T),k(Y),k(U),k(I),k(O),k(P),
-        k2(CAPS,CAPS_LOCK),      k(A),k(S),k(D),k(F),k(G),k(H),k(J),k(K),k(L), k(ENTER),
-        k2(LSHIFT,LEFT_SHIFT),       k(Z),k(X),k(C),k(V),k(B),k(N),k(M),  k2(RSHIFT,RIGHT_SHIFT),                      k(UP),
-        k2(LCTRL,LEFT_CONTROL),k2(LALT,LEFT_ALT), k(SPACE), k2(RALT,RIGHT_ALT),k2(RCTRL,RIGHT_CONTROL), k(LEFT),k(DOWN),k(RIGHT),
-
-        k(F1),k(F2),k(F3),k(F4),k(F5),k(F6),k(F7),k(F8),k(F9),k(F10),k(F11),k(F12), k2(PRINT,PRINT_SCREEN),k(PAUSE),
-        k2(INS,INSERT),k(HOME),k2(PGUP,PAGE_UP), k2(DEL,DELETE),k(END), k2(PGDN,PAGE_DOWN),
-    };
-    #undef k
-    #undef k2
-    any_key = 0;
-    for(int i = 0; i < countof(table); ++i) {
-#if is(ems)
-        if( table[i] ) any_key |= (bits[i] = glfwGetKey(win, table[i] ) == GLFW_PRESS);
-#else
-        any_key |= (bits[i] = glfwGetKeys(win)[ table[i] ]);
-#endif
-    }
-    // special cases: plain shift/alt/ctrl enums will also check right counterparts
-    any_key |= (bits[KEY_ALT] |= glfwGetKey(win, table[KEY_RALT] ) == GLFW_PRESS);
-    any_key |= (bits[KEY_CTRL] |= glfwGetKey(win, table[KEY_RCTRL] ) == GLFW_PRESS);
-    any_key |= (bits[KEY_SHIFT] |= glfwGetKey(win, table[KEY_RSHIFT] ) == GLFW_PRESS);
-
-#if is(ems)
-    {
-        int jid = 0; // @fixme
-        EmscriptenGamepadEvent state = {0};
-
-        if( emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS ) {
-            if( emscripten_get_gamepad_status(jid, &state) == EMSCRIPTEN_RESULT_SUCCESS ) {
-                // hardcoded for Xbox controller
-                if( state.numAxes >= 4 && state.numButtons >= 16 ) {
-
-                    bits[GAMEPAD_CONNECTED] = 1; // !!state.connected
-                    strings[GAMEPAD_GUID] = va("%s", state.id);
-                    strings[GAMEPAD_NAME] = va("emscripten %s", state.mapping);
-                    floats[GAMEPAD_BATTERY] = 100;
-
-                    // e.digitalButton[i], e.analogButton[i]
-
-                    bits[GAMEPAD_A] = state.analogButton[0]; // cross
-                    bits[GAMEPAD_B] = state.analogButton[1]; // circle
-                    bits[GAMEPAD_X] = state.analogButton[2]; // square
-                    bits[GAMEPAD_Y] = state.analogButton[3]; // triangle
-
-                    bits[GAMEPAD_UP] = state.analogButton[12];
-                    bits[GAMEPAD_DOWN] = state.analogButton[13];
-                    bits[GAMEPAD_LEFT] = state.analogButton[14];
-                    bits[GAMEPAD_RIGHT] = state.analogButton[15];
-
-                    bits[GAMEPAD_LB] = state.analogButton[4];
-                    bits[GAMEPAD_RB] = state.analogButton[5];
-                    bits[GAMEPAD_MENU] = state.analogButton[8];
-                    bits[GAMEPAD_START] = state.analogButton[9];
-
-                    bits[GAMEPAD_LTHUMB] = state.analogButton[10];
-                    bits[GAMEPAD_RTHUMB] = state.analogButton[11];
-
-                    floats[GAMEPAD_LT] = state.analogButton[6];
-                    floats[GAMEPAD_RT] = state.analogButton[7];
-
-                    floats[GAMEPAD_LPADX] = state.axis[0];
-                    floats[GAMEPAD_LPADY] = -state.axis[1];
-
-                    floats[GAMEPAD_RPADX] = state.axis[2];
-                    floats[GAMEPAD_RPADY] = -state.axis[3];
-                }
-            }
-        }
-
-        if( 0 && ui_panel("emspad", 0)) {
-            for(int i = 0; i <= 5; ++i )
-            ui_label(va("axis #%d: %5.2f", i, (float)state.axis[i]));
-
-            for(int i = 0; i <= 15; ++i )
-            ui_label(va("button #%d: %d %5.2f", i, state.digitalButton[i], (float)state.analogButton[i]));
-
-            ui_panel_end();
-        }
-    }
-#else
-    int jid = GLFW_JOYSTICK_1 + 0; // @fixme
-    if( glfwGetGamepadName(jid) ) { // glfwJoystickPresent(jid) && glfwJoystickIsGamepad(jid) ) {
-        bits[GAMEPAD_CONNECTED] = 1;
-        strings[GAMEPAD_GUID] = glfwGetJoystickGUID(jid);
-        strings[GAMEPAD_NAME] = glfwGetGamepadName(jid);
-        floats[GAMEPAD_BATTERY] = 100; //glfwJoystickCurrentPowerLevel(jid);
-
-        GLFWgamepadstate state;
-        if (glfwGetGamepadState(jid, &state)) {
-            bits[GAMEPAD_A] = state.buttons[GLFW_GAMEPAD_BUTTON_A]; // cross
-            bits[GAMEPAD_B] = state.buttons[GLFW_GAMEPAD_BUTTON_B]; // circle
-            bits[GAMEPAD_X] = state.buttons[GLFW_GAMEPAD_BUTTON_X]; // square
-            bits[GAMEPAD_Y] = state.buttons[GLFW_GAMEPAD_BUTTON_Y]; // triangle
-
-            bits[GAMEPAD_UP] = state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_UP];
-            bits[GAMEPAD_DOWN] = state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_DOWN];
-            bits[GAMEPAD_LEFT] = state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_LEFT];
-            bits[GAMEPAD_RIGHT] = state.buttons[GLFW_GAMEPAD_BUTTON_DPAD_RIGHT];
-
-            bits[GAMEPAD_LB] = state.buttons[GLFW_GAMEPAD_BUTTON_LEFT_BUMPER];
-            bits[GAMEPAD_RB] = state.buttons[GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER];
-            bits[GAMEPAD_MENU] = state.buttons[GLFW_GAMEPAD_BUTTON_BACK];
-            bits[GAMEPAD_START] = state.buttons[GLFW_GAMEPAD_BUTTON_START]; // _GUIDE
-
-            bits[GAMEPAD_LTHUMB] = state.buttons[GLFW_GAMEPAD_BUTTON_LEFT_THUMB];
-            bits[GAMEPAD_RTHUMB] = state.buttons[GLFW_GAMEPAD_BUTTON_RIGHT_THUMB];
-
-            floats[GAMEPAD_LT] = input_filter_positive(state.axes[GLFW_GAMEPAD_AXIS_LEFT_TRIGGER]); // [-1..+1] -> [0..1]
-            floats[GAMEPAD_RT] = input_filter_positive(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER]); // [-1..+1] -> [0..1]
-
-            floats[GAMEPAD_LPADX] = state.axes[GLFW_GAMEPAD_AXIS_LEFT_X];
-            floats[GAMEPAD_LPADY] = -state.axes[GLFW_GAMEPAD_AXIS_LEFT_Y];
-
-            floats[GAMEPAD_RPADX] = state.axes[GLFW_GAMEPAD_AXIS_RIGHT_X];
-            floats[GAMEPAD_RPADY] = -state.axes[GLFW_GAMEPAD_AXIS_RIGHT_Y];
-        }
-    }
-#endif
-
-    *input_logger(0,+1) = controller[0];
-}
-
-int input_use(int id) {
-    return controller_id >= 0 && controller_id <= 3 ? controller_id = id, 1 : 0;
-}
-
-float input_frame( int vk, int frame ) {
-    if( controller_id > 0 ) return 0; // @fixme
-    struct controller_t *c = input_logger(frame, +0);
-    if(vk < GAMEPAD_LPADX) return c->bits[vk]; // if in bits...
-    if(vk < GAMEPAD_GUID) return c->floats[vk - GAMEPAD_LPADX]; // if in floats...
-    return 0.f; // NAN?
-}
-vec2 input_frame2( int vk, int frame ) {
-    return vec2( input_frame(vk, frame), input_frame(vk+1, frame) );
-}
-
-const char *input_string( int vk ) {
-    int frame = 0;
-    if( controller_id > 0 ) return ""; // @fixme
-    struct controller_t *c = input_logger(frame, +0);
-    return vk >= GAMEPAD_GUID ? c->strings[vk - GAMEPAD_GUID] : ""; // if in strings...
-}
-
-// --- sugars
-
-float input_diff( int vk ) {
-    return input_frame(vk, 0) - input_frame(vk, -1);
-}
-vec2 input_diff2( int vk ) {
-    return vec2( input_diff(vk), input_diff(vk+1) );
-}
-float input( int vk ) {
-    return input_frame( vk, 0 );
-}
-vec2 input2( int vk ) {
-    return vec2( input_frame(vk, 0), input_frame(vk+1, 0) );
-}
-
-// --- events
-
-const float MS2FRAME = 0.06f; // 60 hz/1000 ms
-
-int event( int vk ) {
-    float v = input_frame(vk,0);
-    return (v * v) > 0;
-}
-int input_chord2( int vk1, int vk2 ) {
-    return event(vk1) && event(vk2);
-}
-int input_chord3( int vk1, int vk2, int vk3 ) {
-    return event(vk1) && input_chord2(vk2, vk3);
-}
-int input_chord4( int vk1, int vk2, int vk3, int vk4 ) {
-    return event(vk1) && input_chord3(vk2, vk3, vk4);
-}
-int input_down( int vk ) {
-    return input_diff(vk) > 0; // input_frame(vk,-1) <= 0 && input_frame(vk,0) > 0;
-}
-int input_held( int vk ) {
-    return input_diff(vk) == 0 && input_frame(vk,0) > 0; // input_frame(vk,-1) > 0 && input_frame(vk,0) > 0;
-}
-int input_up( int vk ) {
-    return input_diff(vk) < 0; // input_frame(vk,-1) > 0 && input_frame(vk,0) <= 0;
-}
-int input_idle( int vk ) {
-    return input_diff(vk) == 0 && input_frame(vk,0) <= 0; // input_frame(vk,-1) <= 0 && input_frame(vk,0) <= 0;
-}
-int input_repeat( int vk, int ms ) { // @fixme: broken
-    assert((unsigned)ms <= 1000);
-    return input_frame(vk,-ms * MS2FRAME ) > 0 && input_frame(vk,-ms * MS2FRAME /2) > 0 && input_frame(vk,0) > 0;
-}
-int input_click( int vk, int ms ) { // @fixme: broken
-    assert((unsigned)ms <= 1000);
-    return input_frame(vk,-ms * MS2FRAME ) <= 0 && input_frame(vk,-ms * MS2FRAME /2) > 0 && input_frame(vk,0) <= 0;
-}
-int input_click2( int vk, int ms ) { // @fixme: broken
-    assert((unsigned)ms <= 1000);
-    return input_frame(vk,-ms * MS2FRAME ) <= 0 && input_frame(vk,-ms * MS2FRAME *3/4) > 0
-    && input_frame(vk,-ms * MS2FRAME *2/4) <= 0 && input_frame(vk,-ms * MS2FRAME *1/4) > 0 && input_frame(vk,0) <= 0;
-}
-
-#undef MS2FRAME
-
-// --- filters
-
-float input_filter_positive( float v ) { // [-1..1] -> [0..1]
-    return ( v + 1 ) * 0.5f;
-}
-vec2  input_filter_positive2( vec2 v ) { // [-1..1] -> [0..1]
-    return scale2(inc2(v,1), 0.5f);
-}
-
-vec2 input_filter_deadzone( vec2 v, float deadzone ) {
-    assert(deadzone > 0);
-    float mag = sqrt( v.x*v.x + v.y*v.y );
-    float nx = v.x / mag, ny = v.y / mag, k = (mag - deadzone) / (1 - deadzone);
-    if( k > 1 ) k = 1; // clamp
-    // k = k * k; // uncomment for a smoother curve
-    return mag < deadzone ? vec2(0, 0) : vec2(nx * k, ny * k);
-}
-
-vec2 input_filter_deadzone_4way( vec2 v, float deadzone ) {
-    assert(deadzone > 0);
-    float v0 = v.x*v.x < deadzone*deadzone ? 0 : v.x;
-    float v1 = v.y*v.y < deadzone*deadzone ? 0 : v.y;
-    return vec2(v0, v1);
-}
-
-int input_enum(const char *vk) {
-    static map(char*,int) m = 0;
-    do_once {
-        map_init_str(m);
-        #define k(VK) map_find_or_add(m, STRINGIZE(VK), KEY_##VK); map_find_or_add(m, STRINGIZE(KEY_##VK), KEY_##VK);
-        k(ESC)
-        k(TICK)  k(1) k(2) k(3) k(4) k(5) k(6) k(7) k(8) k(9) k(0)     k(BS)
-        k(TAB)    k(Q) k(W) k(E) k(R) k(T) k(Y) k(U) k(I) k(O) k(P)
-        k(CAPS)       k(A) k(S) k(D) k(F) k(G) k(H) k(J) k(K) k(L)  k(ENTER)
-        k(LSHIFT)        k(Z) k(X) k(C) k(V) k(B) k(N) k(M)        k(RSHIFT)             k(UP)
-        k(LCTRL) k(LALT)                 k(SPACE)           k(RALT) k(RCTRL)    k(LEFT) k(DOWN) k(RIGHT)
-
-        k(F1) k(F2) k(F3) k(F4) k(F5) k(F6) k(F7) k(F8) k(F9) k(F10) k(F11) k(F12)  k(PRINT) k(PAUSE)
-        k(INS) k(HOME) k(PGUP)  k(DEL) k(END)  k(PGDN)
-
-        k(ALT) k(CTRL) k(SHIFT)
-        #undef k
-    };
-    int *found = map_find(m, (char*)vk);
-    return found ? *found : -1;
-}
-
-int input_eval(const char *expression) {
-    if( expression && expression[0] ) {
-        return eval(expression) > 0;
-    }
-    return 0;
-}
-
-// converts keyboard code to its latin char (if any)
-char input_keychar(unsigned code) {
-    #define k2(VK,GLFW) [KEY_##VK] = GLFW_KEY_##GLFW
-    #define k(VK) k2(VK,VK)
-    int table[256] = {
-        k2(ESC,ESCAPE),
-        k2(TICK,GRAVE_ACCENT), k(1),k(2),k(3),k(4),k(5),k(6),k(7),k(8),k(9),k(0), k2(BS,BACKSPACE),
-        k(TAB),                k(Q),k(W),k(E),k(R),k(T),k(Y),k(U),k(I),k(O),k(P),
-        k2(CAPS,CAPS_LOCK),      k(A),k(S),k(D),k(F),k(G),k(H),k(J),k(K),k(L), k(ENTER),
-        k2(LSHIFT,LEFT_SHIFT),       k(Z),k(X),k(C),k(V),k(B),k(N),k(M),  k2(RSHIFT,RIGHT_SHIFT),                k(UP),
-        k2(LCTRL,LEFT_CONTROL),k2(LALT,LEFT_ALT), k(SPACE), k2(RALT,RIGHT_ALT),k2(RCTRL,RIGHT_CONTROL), k(LEFT),k(DOWN),k(RIGHT),
-
-        k(F1),k(F2),k(F3),k(F4),k(F5),k(F6),k(F7),k(F8),k(F9),k(F10),k(F11),k(F12), k2(PRINT,PRINT_SCREEN),k(PAUSE),
-        k2(INS,INSERT),k(HOME),k2(PGUP,PAGE_UP), k2(DEL,DELETE),k(END), k2(PGDN,PAGE_DOWN),
-    };
-    #undef k
-    #undef k2
-
-    code = table[ code & 255 ];
-
-    const char* name = glfwGetKeyName(code, 0);
-    if( name && strlen(name) == 1 ) {
-        return *name >= 'A' && *name <= 'Z' ? name[0] - 'A' + 'a' : name[0];
-    }
-
-    if( code >= GLFW_KEY_0 && code <= GLFW_KEY_9 ) return code - GLFW_KEY_0 + '0';
-    if( code >= GLFW_KEY_A && code <= GLFW_KEY_Z ) return code - GLFW_KEY_A + 'a';
-    switch(code) {
-        default: break;
-        case GLFW_KEY_APOSTROPHE:    return '\'';
-        case GLFW_KEY_BACKSLASH:     return '\\';
-        case GLFW_KEY_COMMA:         return ',';
-        case GLFW_KEY_EQUAL:         return '=';
-        case GLFW_KEY_GRAVE_ACCENT:  return '`';
-        case GLFW_KEY_LEFT_BRACKET:  return '[';
-        case GLFW_KEY_MINUS:         return '-';
-        case GLFW_KEY_PERIOD:        return '.';
-        case GLFW_KEY_RIGHT_BRACKET: return ']';
-        case GLFW_KEY_SEMICOLON:     return ';';
-        case GLFW_KEY_SLASH:         return '/';
-        //case GLFW_KEY_WORLD_1:     return non-US #1;
-        //case GLFW_KEY_WORLD_2:     return non-US #2;
-    }
-
-    return '\0';
-}
-
-// -- multi-touch input
-// multi-touch(emscripten) port based on code by @procedural (MIT-0 licensed)
-
-#if !is(ems)
-
-void touch_init() {}
-void touch_flush() {}
-void input_touch_area(unsigned button, vec2 from, vec2 to)  {}
-vec2 input_touch(unsigned button, float sensitivity) { return vec2(0,0); }
-vec2 input_touch_delta_from_origin(unsigned button, float sensitivity) { return vec2(0,0); }
-vec2 input_touch_delta(unsigned button, float sensitivity) { return vec2(0,0); }
-bool input_touch_active() { return false; }
-
-#else
-
-static struct touch {
-    bool init;
-    vec2 move, cached, origin, prev;
-    vec4 area;
-} touch[2] = {0};
-
-static EM_BOOL touch_move(int eventType, const EmscriptenTouchEvent *e, void *userData) {
-    for( int i = 0; i < (int)e->numTouches; ++i) {
-        if( !e->touches[i].isChanged ) continue;
-        int j = e->touches[i].identifier;
-        if( j >= countof(touch) ) continue;
-
-        touch[j].cached = vec2(e->touches[i].clientX, e->touches[i].clientY);
-        if (!touch[j].init) touch[j].init = 1, touch[j].origin = touch[j].prev = touch[j].move = touch[j].cached;
-    }
-
-    return EM_TRUE;
-}
-
-static EM_BOOL touch_end(int eventType, const EmscriptenTouchEvent *e, void *userData) {
-    for( int i = 0; i < (int)e->numTouches; ++i) {
-        if( !e->touches[i].isChanged ) continue;
-        int j = e->touches[i].identifier;
-        if( j >= countof(touch) ) continue;
-
-        //memset(&touch[j], 0, sizeof(touch[j]));
-        touch[j].init = false;
-        touch[j].move = touch[j].cached = touch[j].origin = touch[j].prev = vec2(0,0);
-    }
-
-    return EM_TRUE;
-}
-
-void input_touch_area(unsigned button, vec2 from_ndc, vec2 to_ndc) {
-    if( button >= countof(touch) ) return;
-    touch[button].area = vec4( from_ndc.x, from_ndc.y, to_ndc.x, to_ndc.y );
-}
-
-void touch_init() {
-    memset(touch, 0, sizeof(touch));
-
-    // default areas: left screen (button #0) and right_screen (button #1)
-    input_touch_area(0, vec2(0.0,0.0), vec2(0.5,1.0));
-    input_touch_area(1, vec2(0.5,0.0), vec2(1.0,1.0));
-
-    emscripten_set_touchstart_callback("#canvas", 0, EM_FALSE, &touch_move);
-    emscripten_set_touchmove_callback("#canvas", 0, EM_FALSE, &touch_move);
-    emscripten_set_touchend_callback("#canvas", 0, EM_FALSE, &touch_end);
-}
-
-void touch_flush() {
-    for( int j = 0; j < countof(touch); ++j) {
-        touch[j].prev = touch[j].move;
-        touch[j].move = touch[j].cached;
-    }
-}
-
-static
-unsigned input_locate_button(unsigned button) {
-    // locate button in user-defined areas
-    vec2 c = window_canvas();
-    for( int j = 0; j < countof(touch); ++j ) {
-        if( touch[j].init )
-        if( touch[j].origin.x >= (touch[button].area.x * c.x) )
-        if( touch[j].origin.y >= (touch[button].area.y * c.y) )
-        if( touch[j].origin.x <= (touch[button].area.z * c.x) )
-        if( touch[j].origin.y <= (touch[button].area.w * c.y) )
-            return j;
-    }
-    return ~0u;
-}
-
-vec2 input_touch(unsigned button, float sensitivity) {
-    button = input_locate_button(button);
-    if( button >= countof(touch) ) return vec2(0,0);
-    return touch[button].init ? touch[button].move : vec2(0,0);
-}
-
-vec2 input_touch_delta(unsigned button, float sensitivity) {
-    button = input_locate_button(button);
-    if( button >= countof(touch) ) return vec2(0,0);
-    return touch[button].init ? scale2( sub2(touch[button].move, touch[button].prev), sensitivity ) : vec2(0,0);
-}
-
-vec2 input_touch_delta_from_origin(unsigned button, float sensitivity) {
-    button = input_locate_button(button);
-    if( button >= countof(touch) ) return vec2(0,0);
-    return touch[button].init ? scale2( sub2(touch[button].move, touch[button].origin), sensitivity ) : vec2(0,0);
-}
-
-bool input_touch_active() {
-    for( int j = 0; j < countof(touch); ++j ) {
-        if( touch[j].init ) return true;
-    }
-    return false;
-}
-
-#endif // !is(ems)
-
-int ui_mouse() {
-    ui_label2_float("X", input(MOUSE_X));
-    ui_label2_float("Y", input(MOUSE_Y));
-    ui_label2_float("Wheel", input(MOUSE_W));
-    ui_separator();
-    ui_label2_bool("Left", input(MOUSE_L));
-    ui_label2_bool("Middle", input(MOUSE_M));
-    ui_label2_bool("Right", input(MOUSE_R));
-    ui_separator();
-    for( int i = 0; i <= CURSOR_SW_AUTO; ++i ) if(ui_button(va("Cursor shape #%d", i))) window_cursor_shape(i);
-
-    return 0;
-}
-
-int ui_keyboard() {
-    char *keys[] = {
-        "F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12",
-        "ESC",
-        "TICK","1","2","3","4","5","6","7","8","9","0","BS",
-        "TAB","Q","W","E","R","T","Y","U","I","O","P",
-        "CAPS","A","S","D","F","G","H","J","K","L","ENTER",
-        "LSHIFT","Z","X","C","V","B","N","M","RSHIFT","^",
-        "LCTRL","LALT","SPACE","RALT","RCTRL","<","V",">",
-    };
-
-    float rows[] = {
-        12,
-        1,
-        12,
-        11,
-        11,
-        10,
-        8
-    };
-
-    for( int row = 0, k = 0; row < countof(rows); ++row ) {
-        static char *buf = 0; if(buf) *buf = 0;
-        for( int col = 0; col < rows[row]; ++col, ++k ) {
-            assert( input_enum(keys[k]) == input_enum(va("KEY_%s", keys[k])) );
-            strcatf(&buf, input(input_enum(keys[k])) ? "[%s]" : " %s ", keys[k]);
-        }
-        ui_label(buf);
-    }
-
-    return 0;
-}
-
-int ui_gamepad(int gamepad_id) {
-    input_use(gamepad_id);
-
-    bool connected = !!input(GAMEPAD_CONNECTED);
-
-    ui_label2("Name", connected ? input_string(GAMEPAD_NAME) : "(Not connected)");
-
-    if( !connected ) ui_disable();
-
-    ui_separator();
-
-    ui_label2_bool("A", input(GAMEPAD_A) );
-    ui_label2_bool("B", input(GAMEPAD_B) );
-    ui_label2_bool("X", input(GAMEPAD_X) );
-    ui_label2_bool("Y", input(GAMEPAD_Y) );
-    ui_label2_bool("Up", input(GAMEPAD_UP) );
-    ui_label2_bool("Down", input(GAMEPAD_DOWN) );
-    ui_label2_bool("Left", input(GAMEPAD_LEFT) );
-    ui_label2_bool("Right", input(GAMEPAD_RIGHT) );
-    ui_label2_bool("Menu", input(GAMEPAD_MENU) );
-    ui_label2_bool("Start", input(GAMEPAD_START) );
-
-    ui_separator();
-
-    ui_label2_float("Left pad x", input(GAMEPAD_LPADX) );
-    ui_label2_float("Left pad y", input(GAMEPAD_LPADY) );
-    ui_label2_float("Left trigger", input(GAMEPAD_LT) );
-    ui_label2_bool("Left bumper", input(GAMEPAD_LB) );
-    ui_label2_bool("Left thumb", input(GAMEPAD_LTHUMB) );
-
-    vec2 v = input_filter_deadzone( input2(GAMEPAD_LPADX), 0.1f );
-    ui_label2_float("Filtered pad x", v.x);
-    ui_label2_float("Filtered pad y", v.y);
-
-    ui_separator();
-
-    ui_label2_float("Right pad x", input(GAMEPAD_RPADX) );
-    ui_label2_float("Right pad y", input(GAMEPAD_RPADY) );
-    ui_label2_float("Right trigger", input(GAMEPAD_RT) );
-    ui_label2_bool("Right bumper", input(GAMEPAD_RB) );
-    ui_label2_bool("Right thumb", input(GAMEPAD_RTHUMB) );
-
-    vec2 w = input_filter_deadzone( input2(GAMEPAD_RPADX), 0.1f );
-    ui_label2_float("Filtered pad x", w.x);
-    ui_label2_float("Filtered pad y", w.y);
-
-    ui_enable();
-
-    input_use(0);
-    return 0;
-}
-
-int ui_gamepads() {
-    for( int i = 0; i < 4; ++i ) ui_gamepad(i);
-
-    return 0;
-}
diff --git a/sfw/render_core/fwk_input.h b/sfw/render_core/fwk_input.h
deleted file mode 100644
index 88cb154..0000000
--- a/sfw/render_core/fwk_input.h
+++ /dev/null
@@ -1,124 +0,0 @@
-// -----------------------------------------------------------------------------
-// input framework
-// - rlyeh, public domain
-//
-// @todo: window
-// @todo: for extra savings (168->72 bytes), promote bits to real bits (/8 %8) & normalized floats [-1,+1] to shorts or chars
-// @todo: GAMEPAD_A|2, MOUSE_L|1, KEY_C|3
-// @todo: load/save
-// @todo: send virtual presses & outputs (rumble, light, led, text, etc)
-// @todo: fix if logger !60 hz
-// @tofo: fix click2/repeat edge cases
-
-API int         input_use( int controller_id ); // [0..3]
-
-// -- basic polling api (read input at current frame)
-
-API float       input( int vk );
-API vec2        input2( int vk );
-API float       input_diff( int vk ); // @todo: rename diff->delta
-API vec2        input_diff2( int vk ); // @todo: rename diff2->delta2
-API const char* input_string( int vk );
-
-// -- extended polling api (read input at Nth frame ago)
-
-API float       input_frame( int vk, int Nth_frame );
-API vec2        input_frame2( int vk, int Nth_frame );
-
-// -- events api
-
-API int         input_up( int vk ); // ON -> OFF (release)
-API int         input_down( int vk ); // OFF -> ON (trigger)
-API int         input_held( int vk ); // ON -> ON (pressed)
-API int         input_idle( int vk ); // OFF -> OFF
-
-API int         input_click( int vk, int ms ); // OFF -> ON -> OFF
-API int         input_click2( int vk, int ms ); // OFF -> ON -> OFF -> ON -> OFF
-API int         input_repeat( int vk, int ms ); // [...] ON -> ON -> ON
-
-API int         input_chord2( int vk1, int vk2 ); // all vk1 && vk2 are ON
-API int         input_chord3( int vk1, int vk2, int vk3 ); // all vk1 && vk2 && vk3 are ON
-API int         input_chord4( int vk1, int vk2, int vk3, int vk4 ); // all vk1 && vk2 && vk3 && vk4 are ON
-
-// -- 1d/2d filters
-
-API float       input_filter_positive( float v ); // [-1..1] -> [0..1]
-API vec2        input_filter_positive2( vec2 v ); // [-1..1] -> [0..1]
-API vec2        input_filter_deadzone( vec2 v, float deadzone_treshold );
-API vec2        input_filter_deadzone_4way( vec2 v, float deadzone_treshold );
-
-// -- multi-touch
-
-enum TOUCH_BUTTONS {
-    TOUCH_0,    // defaults to left screen area. input_touch_area() to override
-    TOUCH_1,    // defaults to right screen area. input_touch_area() to override
-};
-
-API void        input_touch_area(unsigned button, vec2 begin_coord_ndc, vec2 end_coord_ndc);
-API vec2        input_touch(unsigned button, float sensitivity);                   // absolute position in 2d coords
-API vec2        input_touch_delta(unsigned button, float sensitivity);             // delta from previous position
-API vec2        input_touch_delta_from_origin(unsigned button, float sensitivity); // relative position from initial touch
-API bool        input_touch_active();
-
-// -- utils
-
-API void        input_mappings(const char *filename); // update gamepad mappings (usually "gamecontrollerdb.txt" file)
-API char        input_keychar(unsigned code); // Converts keyboard code to its latin char (if any)
-API int         input_enum(const char *sym);
-API int         input_anykey();
-API int         input_eval(const char *expression); // "down(X)*input(CTRL)"
-
-// inject state
-API void        input_send( int vk ); // @todo
-// load/save input
-API array(char) save_input(); // @todo
-API bool        load_input(array(char) replay); // @todo
-
-// visualize input
-API int         ui_keyboard();
-API int         ui_mouse();
-API int         ui_gamepad(int id);
-API int         ui_gamepads();
-
-// --
-
-enum INPUT_ENUMS {
-    // -- bits: x104 keyboard, x3 mouse, x15 gamepad, x7 window
-    // keyboard gaming keys (53-bit): first-class keys for gaming
-    KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9,   KEY_TICK,KEY_BS,           KEY_ESC,
-    KEY_TAB,   KEY_Q,KEY_W,KEY_E,KEY_R,KEY_T,KEY_Y,KEY_U,KEY_I,KEY_O,KEY_P,
-    KEY_CAPS,     KEY_A,KEY_S,KEY_D,KEY_F,KEY_G,KEY_H,KEY_J,KEY_K,KEY_L, KEY_ENTER,
-    KEY_LSHIFT,       KEY_Z,KEY_X,KEY_C,KEY_V,KEY_B,KEY_N,KEY_M,        KEY_RSHIFT,            KEY_UP,
-    KEY_LCTRL,KEY_LALT,               KEY_SPACE,                KEY_RALT,KEY_RCTRL,  KEY_LEFT,KEY_DOWN,KEY_RIGHT,
-
-    // for completeness, secondary keys below (52-bit). beware!
-    KEY_INS,KEY_HOME,KEY_PGUP,KEY_DEL,KEY_END,KEY_PGDN, // beware: different behavior win/osx (also, osx: no home/end).
-    KEY_LMETA,KEY_RMETA,KEY_MENU,KEY_PRINT,KEY_PAUSE,KEY_SCROLL,KEY_NUMLOCK, // beware: may trigger unexpected OS behavior. (@todo: add RSHIFT here for win?)
-    KEY_MINUS,KEY_EQUAL,KEY_LSQUARE,KEY_RSQUARE,KEY_SEMICOLON,KEY_QUOTE,KEY_HASH,KEY_BAR,KEY_COMMA,KEY_DOT,KEY_SLASH, // beware: non-us keyboard layouts
-    KEY_F1,KEY_F2,KEY_F3,KEY_F4,KEY_F5,KEY_F6,KEY_F7,KEY_F8,KEY_F9,KEY_F10,KEY_F11,KEY_F12, // beware: complicated on laptops/osx
-    KEY_PAD1,KEY_PAD2,KEY_PAD3,KEY_PAD4,KEY_PAD5,KEY_PAD6,KEY_PAD7,KEY_PAD8,KEY_PAD9,KEY_PAD0, // beware: complicated on laptops
-    KEY_PADADD,KEY_PADSUB,KEY_PADMUL,KEY_PADDIV,KEY_PADDOT,KEY_PADENTER, // beware: complicated on laptops
-
-    MOUSE_L, MOUSE_M, MOUSE_R, // @todo: MOUSE_CLICKS,
-    GAMEPAD_CONNECTED, GAMEPAD_A, GAMEPAD_B, GAMEPAD_X, GAMEPAD_Y,
-    GAMEPAD_UP, GAMEPAD_DOWN, GAMEPAD_LEFT, GAMEPAD_RIGHT, GAMEPAD_MENU, GAMEPAD_START,
-    GAMEPAD_LB, GAMEPAD_RB, GAMEPAD_LTHUMB, GAMEPAD_RTHUMB,
-    WINDOW_BLUR, WINDOW_FOCUS, WINDOW_CLOSE, WINDOW_MINIMIZE, WINDOW_MAXIMIZE, WINDOW_FULLSCREEN, WINDOW_WINDOWED, // MINI/MAXI/RESTORED, SHOWN/HIDDEN
-
-    // -- floats: x7 gamepad, x3 mouse, x4 touch, x4 window
-    GAMEPAD_LPAD, GAMEPAD_LPADX = GAMEPAD_LPAD, GAMEPAD_LPADY,
-    GAMEPAD_RPAD, GAMEPAD_RPADX = GAMEPAD_RPAD, GAMEPAD_RPADY,
-    GAMEPAD_LTRIGGER, GAMEPAD_LT = GAMEPAD_LTRIGGER, GAMEPAD_RTRIGGER, GAMEPAD_RT = GAMEPAD_RTRIGGER, GAMEPAD_BATTERY,
-    MOUSE, MOUSE_X = MOUSE, MOUSE_Y, MOUSE_W,
-    TOUCH_X1, TOUCH_Y1, TOUCH_X2, TOUCH_Y2,
-    WINDOW_RESIZE, WINDOW_RESIZEX = WINDOW_RESIZE, WINDOW_RESIZEY, WINDOW_ORIENTATION, WINDOW_BATTERY,
-
-    // -- strings: x2 gamepad
-    GAMEPAD_GUID, GAMEPAD_NAME,
-};
-// these aliases do check both left and right counterparts
-enum INPUT_ALIASES {
-    KEY_SHIFT = KEY_LSHIFT,
-    KEY_ALT = KEY_LALT,
-    KEY_CTRL = KEY_LCTRL,
-};
diff --git a/sfw/render_core/input/input.cpp b/sfw/render_core/input.cpp
similarity index 99%
rename from sfw/render_core/input/input.cpp
rename to sfw/render_core/input.cpp
index 414ad33..d358eaa 100644
--- a/sfw/render_core/input/input.cpp
+++ b/sfw/render_core/input.cpp
@@ -8,8 +8,8 @@
 #include "core/logger.h"
 #include "core/stime.h"
 #include "render_core/application.h"
-#include "render_core/input/input_map.h"
-#include "render_core/input/keyboard.h"
+#include "render_core/input_map.h"
+#include "render_core/keyboard.h"
 #include "render_core/texture.h"
 #include "render_core/window.h"
 
diff --git a/sfw/render_core/input/input.h b/sfw/render_core/input.h
similarity index 99%
rename from sfw/render_core/input/input.h
rename to sfw/render_core/input.h
index eb84b54..95e0fa8 100644
--- a/sfw/render_core/input/input.h
+++ b/sfw/render_core/input.h
@@ -14,7 +14,7 @@
 #include "core/thread_safe.h"
 #include "object/psignal.h"
 #include "object/reference.h"
-#include "render_core/input/input_event.h"
+#include "render_core/input_event.h"
 
 class Application;
 struct GLFWwindow;
diff --git a/sfw/render_core/input/input_event.cpp b/sfw/render_core/input_event.cpp
similarity index 99%
rename from sfw/render_core/input/input_event.cpp
rename to sfw/render_core/input_event.cpp
index 77937fd..e06a121 100644
--- a/sfw/render_core/input/input_event.cpp
+++ b/sfw/render_core/input_event.cpp
@@ -5,9 +5,9 @@
 
 #include "input_event.h"
 
-#include "render_core/input/input_map.h"
-#include "render_core/input/keyboard.h"
-#include "render_core/input/shortcut.h"
+#include "render_core/input_map.h"
+#include "render_core/keyboard.h"
+#include "render_core/shortcut.h"
 
 const int InputEvent::DEVICE_ID_TOUCH_MOUSE = -1;
 const int InputEvent::DEVICE_ID_INTERNAL = -2;
diff --git a/sfw/render_core/input/input_event.h b/sfw/render_core/input_event.h
similarity index 100%
rename from sfw/render_core/input/input_event.h
rename to sfw/render_core/input_event.h
diff --git a/sfw/render_core/input/input_map.cpp b/sfw/render_core/input_map.cpp
similarity index 99%
rename from sfw/render_core/input/input_map.cpp
rename to sfw/render_core/input_map.cpp
index 790a736..fde00cd 100644
--- a/sfw/render_core/input/input_map.cpp
+++ b/sfw/render_core/input_map.cpp
@@ -5,8 +5,8 @@
 
 #include "input_map.h"
 
-#include "render_core/input/input.h"
-#include "render_core/input/keyboard.h"
+#include "render_core/input.h"
+#include "render_core/keyboard.h"
 
 InputMap *InputMap::singleton = nullptr;
 
diff --git a/sfw/render_core/input/input_map.h b/sfw/render_core/input_map.h
similarity index 98%
rename from sfw/render_core/input/input_map.h
rename to sfw/render_core/input_map.h
index cca293b..8203c44 100644
--- a/sfw/render_core/input/input_map.h
+++ b/sfw/render_core/input_map.h
@@ -6,7 +6,7 @@
 /*  From https://github.com/Relintai/pandemonium_engine (MIT)            */
 /*************************************************************************/
 
-#include "render_core/input/input_event.h"
+#include "render_core/input_event.h"
 #include "object/object.h"
 #include "core/rb_map.h"
 
diff --git a/sfw/render_core/input/keyboard.cpp b/sfw/render_core/keyboard.cpp
similarity index 100%
rename from sfw/render_core/input/keyboard.cpp
rename to sfw/render_core/keyboard.cpp
diff --git a/sfw/render_core/input/keyboard.h b/sfw/render_core/keyboard.h
similarity index 100%
rename from sfw/render_core/input/keyboard.h
rename to sfw/render_core/keyboard.h
diff --git a/sfw/render_core/scene.cpp b/sfw/render_core/scene.cpp
index c9451bc..7bf6aee 100644
--- a/sfw/render_core/scene.cpp
+++ b/sfw/render_core/scene.cpp
@@ -1,6 +1,6 @@
 #include "render_core/scene.h"
 
-#include "render_core/input/input_event.h"
+#include "render_core/input_event.h"
 
 void Scene::input_event(const Ref<InputEvent> &event) {
 }
diff --git a/sfw/render_core/scene.h b/sfw/render_core/scene.h
index 88c02cc..323a861 100644
--- a/sfw/render_core/scene.h
+++ b/sfw/render_core/scene.h
@@ -2,7 +2,7 @@
 #define SCENE_H
 
 #include "object/reference.h"
-#include "render_core/input/input_event.h"
+#include "render_core/input_event.h"
 
 class Scene : public Reference {
 	SFW_OBJECT(Scene, Reference);
diff --git a/sfw/render_core/input/shortcut.cpp b/sfw/render_core/shortcut.cpp
similarity index 95%
rename from sfw/render_core/input/shortcut.cpp
rename to sfw/render_core/shortcut.cpp
index bdc9165..78ac0d2 100644
--- a/sfw/render_core/input/shortcut.cpp
+++ b/sfw/render_core/shortcut.cpp
@@ -5,7 +5,7 @@
 
 #include "shortcut.h"
 
-#include "render_core/input/input_event.h"
+#include "render_core/input_event.h"
 
 void ShortCut::set_shortcut(const Ref<InputEvent> &p_shortcut) {
 	shortcut = p_shortcut;
diff --git a/sfw/render_core/input/shortcut.h b/sfw/render_core/shortcut.h
similarity index 100%
rename from sfw/render_core/input/shortcut.h
rename to sfw/render_core/shortcut.h
diff --git a/sfw/render_core/window.cpp b/sfw/render_core/window.cpp
index 2ce7703..49c25a5 100644
--- a/sfw/render_core/window.cpp
+++ b/sfw/render_core/window.cpp
@@ -28,7 +28,7 @@
 #include "core/ustring.h"
 #include "core/vector4.h"
 #include "render_core/application.h"
-#include "render_core/input/input.h"
+#include "render_core/input.h"
 
 /*
 static volatile float framerate = 0;