Explorar el Código

Merge branch 'master' into piaf_integration

Eiyeron Fulmincendii hace 10 años
padre
commit
60a27b6b6c

+ 4 - 0
.gitignore

@@ -7,3 +7,7 @@ config.mk
 
 # Atom editor files
 .atom-build.json
+
+# Sublime
+*.sublime-project
+*.sublime-workspace

+ 1 - 1
.ycm_extra_conf.py

@@ -38,7 +38,7 @@ import subprocess
 flags = [
 '-Wall',
 '-Wextra',
-'-Werror',
+#'-Werror',
 '-Wno-long-long',
 '-Wno-variadic-macros',
 '-fexceptions',

+ 1 - 1
Makefile

@@ -2,7 +2,7 @@ NAME = WalrusRPG
 
 DEBUG = FALSE
 
-CFLAGS_COMMON = -Wall -W $(addprefix -I,$(INCLUDE) $(INCLUDE_EXT)) -MMD -MP
+CFLAGS_COMMON = -Wall -W $(addprefix -I,$(INCLUDE) $(INCLUDE_EXT)) -MMD -MP -pipe
 
 ifeq ($(DEBUG),FALSE)
 	CFLAGS_COMMON += -Ofast -flto

+ 27 - 2
mkconfig

@@ -1,6 +1,31 @@
 #!/bin/bash
 
-rm -f config.mk
+TARGET_LIST=("nspire" "sfml")
 
-echo "include platform/nspire/rules.mk" >> config.mk
+create_configuration() {
+	echo "Creating $1 configuration"
+	rm config.mk -f
+	echo "include platform/$1/rules.mk" >> config.mk
+}
 
+is_valid_target() {
+	for item in "${TARGET_LIST[@]}"; do
+		[[ $1 == "$item" ]] && return 0
+	done
+	return 1
+}
+
+old_PS3=PS3
+PS3='#? '
+# If $1 isn't set
+if [[ -z ${1+z} ]]; then
+	echo "Platform:"
+	select TARGET in "${TARGET_LIST[@]}"; do
+		create_configuration "$TARGET"
+		[[ $TARGET == "" ]] || break
+	done
+# else use it as a platform selection
+else
+	is_valid_target "$1" && create_configuration "$1"
+fi
+PS3=old_PS3

+ 43 - 5
platform/include/Graphics.h

@@ -31,18 +31,56 @@ namespace WalrusRPG
         void frame_end();
 
         /*
-         * Current prototype is the same as the nspire fb implementation
-         * for now, need to add a texture type and get rid of the Rect
-         * (not sure the GC supports drawing parts of a texture, but it
-         * may be worth trying
+         * Draws a sprite with clipping given as window.
          */
-        void put_sprite(const Texture &sheet, int x, int y,
+        void put_sprite(const WalrusRPG::Graphics::Texture &sheet, int x, int y,
                         const WalrusRPG::Utils::Rect &window);
 
+        /*
+         * Draws a sprite with clipping given as window and color
+         * tinting.
+         */
+        void put_sprite_tint(const Texture &sheet, int x, int y,
+                             const WalrusRPG::Utils::Rect &window,
+                             const WalrusRPG::Graphics::Pixel &color);
+
         /*
          * Fill the screen with a color
          */
         void fill(const WalrusRPG::Graphics::Pixel &color);
+
+        /*
+         * Draws a pixel on the screen.
+         */
+        void put_pixel(uint16_t x, uint16_t y, const WalrusRPG::Graphics::Pixel &color);
+
+        // Primitives drawing
+
+        /*
+         * Draws an horizontal line on the screen.
+         */
+        void put_horizontal_line(uint16_t x, uint16_t x2, uint16_t y,
+                                 const WalrusRPG::Graphics::Pixel &color);
+
+        /*
+         * Draws an vertical line on the screen.
+         */
+        void put_vertical_line(uint16_t x, uint16_t y, uint16_t y2,
+                               const WalrusRPG::Graphics::Pixel &color);
+
+        /*
+         * Draws a line on the screen. As it uses Bresenham's algorithm, it won't be the
+         * most optimized way
+         * to draw vertical or horizontal lines.
+         */
+        void put_line(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2,
+                      const WalrusRPG::Graphics::Pixel &color);
+
+        /*
+         * Draws a filled rectangle on the screen.
+         */
+        void put_rectangle(const WalrusRPG::Utils::Rect &rect,
+                           const WalrusRPG::Graphics::Pixel &color);
     }
 }
 

+ 30 - 6
platform/include/Input.h

@@ -5,12 +5,36 @@ namespace WalrusRPG
 {
     namespace Input
     {
-        bool key_a();
-        bool key_b();
-        bool key_up();
-        bool key_down();
-        bool key_left();
-        bool key_right();
+        enum Key
+        {
+            K_A,
+            K_B,
+            K_L,
+            K_R,
+            K_UP,
+            K_DOWN,
+            K_LEFT,
+            K_RIGHT,
+            K_START,
+            K_SELECT,
+            K_SIZE
+        };
+
+        enum KeyState
+        {
+            KS_RELEASED,
+            KS_JUST_RELEASED,
+            KS_JUST_PRESSED,
+            KS_PRESSED
+        };
+
+
+        void key_poll();
+
+        bool key_pressed(Key key);
+        bool key_released(Key key);
+        bool key_down(Key key);
+        bool key_up(Key key);
     }
 }
 

+ 26 - 0
platform/nspire/CXfb.cpp

@@ -112,6 +112,14 @@ void GRAPHICS::draw_pixel(int x, int y, uint16_t color)
     buffer_render[x + (y * 320)] = color;
 }
 
+void GRAPHICS::draw_pixel_tint(int x, int y, uint16_t color, uint16_t tint)
+{
+    int r = ((color >> 11) * (tint >> 11)) >> 5;
+    int g = (((color >> 5) & 0b111111) * ((tint >> 5) & 0b111111)) >> 6;
+    int b = ((color & 0b11111) * (tint & 0b11111)) >> 5;
+    buffer_render[x + (y * 320)] = (r << 11) | (g << 5) | b;
+}
+
 void GRAPHICS::draw_sprite_sheet(const uint16_t *sheet, int x, int y,
                                  const WalrusRPG::Utils::Rect &window)
 {
@@ -130,6 +138,24 @@ void GRAPHICS::draw_sprite_sheet(const uint16_t *sheet, int x, int y,
     }
 }
 
+void GRAPHICS::draw_sprite_sheet_tint(const uint16_t *sheet, int x, int y,
+                                      const WalrusRPG::Utils::Rect &window, uint16_t tint)
+{
+    uint16_t color;
+    int w = min(window.width + x, 320);
+    int h = min(window.height + y, 240);
+
+    for (int j = max(y, 0), l = window.y - min(y, 0); j < h; j++, l++)
+    {
+        for (int i = max(x, 0), k = window.x - min(x, 0); i < w; i++, k++)
+        {
+            color = sprite_pixel_get(sheet, k, l);
+            if (color != sheet[2])
+                draw_pixel_tint(i, j, color, tint);
+        }
+    }
+}
+
 
 /*
  * Sprite manipulation

+ 3 - 0
platform/nspire/CXfb.h

@@ -30,8 +30,11 @@ namespace Nspire
          */
 
         void draw_pixel(int x, int y, uint16_t color);
+        void draw_pixel_tint(int x, int y, uint16_t color, uint16_t tint);
         void draw_sprite_sheet(const uint16_t *sheet, int x, int y,
                                const WalrusRPG::Utils::Rect &window);
+        void draw_sprite_sheet_tint(const uint16_t *sheet, int x, int y,
+                                    const WalrusRPG::Utils::Rect &window, uint16_t tint);
 
 
         /*

+ 101 - 9
platform/nspire/Graphics.cpp

@@ -1,37 +1,129 @@
 #include "Graphics.h"
 #include "CXfb.h"
 #include "stdio.h"
-
-#define GRAPHICS WalrusRPG::Graphics
+#include "utility/misc.h"
 
 using namespace Nspire;
+using namespace WalrusRPG;
+using WalrusRPG::Graphics::Texture;
+using WalrusRPG::Graphics::Pixel;
+using WalrusRPG::Utils::Rect;
 
-void GRAPHICS::init()
+void Graphics::init()
 {
     CXfb::buffer_allocate();
 }
 
-void GRAPHICS::deinit()
+void Graphics::deinit()
 {
     CXfb::buffer_free();
 }
 
-void GRAPHICS::frame_begin()
+void Graphics::frame_begin()
 {
 }
 
-void GRAPHICS::frame_end()
+void Graphics::frame_end()
 {
     CXfb::buffer_swap_render();
 }
 
-void GRAPHICS::put_sprite(const Texture &sheet, int x, int y,
-                          const WalrusRPG::Utils::Rect &window)
+void Graphics::put_sprite(const Texture &sheet, int x, int y, const Rect &window)
 {
     CXfb::draw_sprite_sheet(sheet.data, x, y, window);
 }
 
-void GRAPHICS::fill(const WalrusRPG::Graphics::Pixel &color)
+void Graphics::put_sprite_tint(const Texture &sheet, int x, int y, const Rect &window,
+                               const Pixel &color)
+{
+    CXfb::draw_sprite_sheet_tint(sheet.data, x, y, window, color.value);
+}
+
+void Graphics::fill(const Pixel &color)
 {
     CXfb::buffer_fill(color);
 }
+
+void Graphics::put_pixel(uint16_t x, uint16_t y, const Pixel &color)
+
+{
+    CXfb::draw_pixel(x, y, color.value);
+}
+
+void Graphics::put_horizontal_line(uint16_t x, uint16_t x2, uint16_t y,
+                                   const Pixel &color)
+{
+    if (x > x2)
+    {
+        uint16_t temp = x;
+        x = x2;
+        x2 = temp;
+    }
+    for (; x < x2; x++)
+    {
+        CXfb::draw_pixel(x, y, color);
+    }
+}
+
+void Graphics::put_vertical_line(uint16_t x, uint16_t y, uint16_t y2, const Pixel &color)
+{
+    if (y > y2)
+    {
+        uint16_t temp = y;
+        y = y2;
+        y2 = temp;
+    }
+    for (; y < y2; y++)
+    {
+        CXfb::draw_pixel(x, y, color);
+    }
+}
+
+void Graphics::put_line(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2,
+                        const Pixel &color)
+{
+    if (x == x2)
+    {
+        put_vertical_line(x, y, y2, color);
+        return;
+    }
+    else if (y == y2)
+    {
+        put_horizontal_line(x, x2, y, color);
+        return;
+    }
+    int dx = abs(x - x2), sx = x < x2 ? 1 : -1;
+    int dy = abs(y - y2), sy = y < y2 ? 1 : -1;
+    int err = (dx > dy ? dx : -dy) / 2, e2;
+
+    for (;;)
+    {
+        put_pixel(x, y, color);
+        if (x == x2 && y == y2)
+            break;
+        e2 = err;
+        if (e2 > -dx)
+        {
+            err -= dy;
+            x += sx;
+        }
+        if (e2 < dy)
+        {
+            err += dx;
+            y += sy;
+        }
+    }
+}
+
+void Graphics::put_rectangle(const Rect &rect, const Pixel &color)
+{
+    uint16_t xmax = min(320, rect.x + rect.width);
+    uint16_t ymax = min(240, rect.y + rect.height);
+    for (uint16_t x = rect.x; x < xmax; x++)
+    {
+        for (uint16_t y = rect.y; y < ymax; y++)
+        {
+            CXfb::draw_pixel(x, y, color.value);
+        }
+    }
+}

+ 52 - 16
platform/nspire/Input.cpp

@@ -3,32 +3,68 @@
 
 #define INPUT WalrusRPG::Input
 
-bool INPUT::key_a()
+using WalrusRPG::Input::Key;
+using WalrusRPG::Input::KeyState;
+
+struct InputMap
 {
-    return isKeyPressed(KEY_NSPIRE_ENTER);
-}
+    Key key;
+    t_key key_code;
+};
+
+static KeyState key_states[Key::K_SIZE] = {KeyState::KS_RELEASED};
+static InputMap key_map[] = {
+    {Key::K_A, KEY_NSPIRE_CTRL},     {Key::K_B, KEY_NSPIRE_SHIFT},
+    {Key::K_L, KEY_NSPIRE_TAB},      {Key::K_R, KEY_NSPIRE_MENU},
+
+    {Key::K_UP, KEY_NSPIRE_8},       {Key::K_DOWN, KEY_NSPIRE_5},
+    {Key::K_LEFT, KEY_NSPIRE_4},     {Key::K_RIGHT, KEY_NSPIRE_6},
+
+    {Key::K_START, KEY_NSPIRE_HOME}, {Key::K_SELECT, KEY_NSPIRE_ESC},
+};
 
-bool INPUT::key_b()
+void INPUT::key_poll()
 {
-    return isKeyPressed(KEY_NSPIRE_ESC);
+    for (unsigned i = 0; i < K_SIZE; i++)
+    {
+        bool current_key_state = isKeyPressed(key_map[i].key_code);
+        KeyState previous_key_state = key_states[i];
+
+        KeyState resulting_key_state = KS_RELEASED;
+        if (current_key_state)
+        {
+            if (previous_key_state == KS_RELEASED ||
+                previous_key_state == KS_JUST_RELEASED)
+                resulting_key_state = KS_JUST_PRESSED;
+            else if (previous_key_state == KS_JUST_PRESSED ||
+                     previous_key_state == KS_PRESSED)
+                resulting_key_state = KS_PRESSED;
+        }
+        else
+        {
+            if (previous_key_state == KS_PRESSED || previous_key_state == KS_JUST_PRESSED)
+                resulting_key_state = KS_JUST_RELEASED;
+            else if (previous_key_state == KS_JUST_RELEASED ||
+                     previous_key_state == KS_RELEASED)
+                resulting_key_state = KS_RELEASED;
+        }
+        key_states[i] = resulting_key_state;
+    }
 }
 
-bool INPUT::key_up()
+bool INPUT::key_pressed(Key key)
 {
-    return isKeyPressed(KEY_NSPIRE_8);
+    return key_states[key] == KS_JUST_PRESSED;
 }
-
-bool INPUT::key_down()
+bool INPUT::key_released(Key key)
 {
-    return isKeyPressed(KEY_NSPIRE_5);
+    return key_states[key] == KS_JUST_RELEASED;
 }
-
-bool INPUT::key_left()
+bool INPUT::key_down(Key key)
 {
-    return isKeyPressed(KEY_NSPIRE_4);
+    return key_states[key] == KS_JUST_PRESSED || key_states[key] == KS_PRESSED;
 }
-
-bool INPUT::key_right()
+bool INPUT::key_up(Key key)
 {
-    return isKeyPressed(KEY_NSPIRE_6);
+    return key_states[key] == KS_JUST_RELEASED || key_states[key] == KS_RELEASED;
 }

+ 4 - 2
platform/nspire/Interrupts.cpp

@@ -30,7 +30,8 @@ void INTERRUPTS::init()
     *interrupt_pointer = (uint32_t) &isr;
 
     // Enable IRQ in the CPU
-    asm("mrs r1, cpsr \n\t"
+    asm(
+        "mrs r1, cpsr \n\t"
         "bic r1, r1, #0x80 \n\t"
         "msr cpsr, r1"
         :
@@ -41,7 +42,8 @@ void INTERRUPTS::init()
 void INTERRUPTS::off()
 {
     // Disable IRQ in the CPU
-    asm("mrs r1, cpsr \n\t"
+    asm(
+        "mrs r1, cpsr \n\t"
         "orr r1, r1, #0x80 \n\t"
         "msr cpsr, r1"
         :

+ 2 - 0
platform/nspire/Texure.cpp

@@ -10,12 +10,14 @@ using WalrusRPG::Utils::Rect;
 
 namespace
 {
+    /*
     texture_data_t loadPNG(char *data)
     {
         // TODO : stuff
         UNUSED(data);
         return nullptr;
     }
+    */
 }
 
 Texture::Texture(char *data) : data((texture_data_t) data)

+ 1 - 0
platform/nspire/public/platform.h

@@ -4,6 +4,7 @@
 #include <cstdint>
 
 #define TIMER_FREQ 32768
+#define ACTIVE_WAIT
 
 typedef uint16_t *texture_data_t;
 

+ 1 - 1
platform/nspire/rules.mk

@@ -4,7 +4,7 @@ SRCS_C += $(wildcard $(nspire_LOCAL_PATH)/platform/*.c)
 SRCS_CPP += $(wildcard $(nspire_LOCAL_PATH)/*.cpp)
 INCLUDE += $(nspire_LOCAL_PATH)/public
 
-CFLAGS_COMMON += -marm
+CFLAGS_COMMON += -marm -DNSPIRE=1
 
 CC = nspire-gcc
 CPP = nspire-g++

+ 64 - 10
platform/sfml/Graphics.cpp

@@ -3,31 +3,35 @@
 #include <SFML/Graphics.hpp>
 #include "utility/misc.h"
 
-#define GRAPHICS WalrusRPG::Graphics
+using namespace WalrusRPG;
+using WalrusRPG::Graphics::Texture;
+using WalrusRPG::Graphics::Pixel;
+using WalrusRPG::Utils::Rect;
 
 sf::RenderWindow window;
 sf::View view;
 sf::RenderTexture buffer;
 
-void GRAPHICS::init()
+void Graphics::init()
 {
-    window.create(sf::VideoMode::getDesktopMode(), "WalrusRPG", sf::Style::Fullscreen);
+    // window.create(sf::VideoMode::getDesktopMode(), "WalrusRPG", sf::Style::Fullscreen);
+    window.create(sf::VideoMode(640, 480), "WalrusRPG");
     window.setFramerateLimit(60);
     view = sf::View(window.getDefaultView());
     buffer.create(320, 240);
 }
 
-void GRAPHICS::deinit()
+void Graphics::deinit()
 {
     window.close();
 }
 
-void GRAPHICS::frame_begin()
+void Graphics::frame_begin()
 {
     window.clear(sf::Color::Black);
 }
 
-void GRAPHICS::frame_end()
+void Graphics::frame_end()
 {
     sf::Sprite sprite(buffer.getTexture());
     sf::Vector2u winsize = window.getSize();
@@ -48,8 +52,8 @@ void GRAPHICS::frame_end()
     window.display();
 }
 
-void GRAPHICS::put_sprite(const Texture &sheet, int x, int y,
-                          const WalrusRPG::Utils::Rect &window)
+void Graphics::put_sprite(const WalrusRPG::Graphics::Texture &sheet, int x, int y,
+                          const Rect &window)
 {
     sf::Sprite sprite;
     sprite.setTexture(sheet.data);
@@ -58,7 +62,57 @@ void GRAPHICS::put_sprite(const Texture &sheet, int x, int y,
     buffer.draw(sprite);
 }
 
-void GRAPHICS::fill(const WalrusRPG::Graphics::Pixel &color)
+void Graphics::put_sprite_tint(const WalrusRPG::Graphics::Texture &sheet, int x, int y,
+                               const Rect &window, const Pixel &color)
 {
-    UNUSED(color);
+    sf::Sprite sprite;
+    sprite.setTexture(sheet.data);
+    sprite.setTextureRect(sf::IntRect(window.x, window.y, window.width, window.height));
+    sprite.setPosition(x, y);
+    sprite.setColor(sf::Color(color.r << 3, color.g << 2, color.b << 3, 255));
+    buffer.draw(sprite);
+}
+
+void Graphics::fill(const Pixel &color)
+{
+    buffer.clear(sf::Color(color.r << 3, color.g << 2, color.b << 2, 255));
+}
+
+void Graphics::put_pixel(uint16_t x, uint16_t y, const Pixel &color)
+{
+    sf::RectangleShape pixel;
+    pixel.setSize(sf::Vector2f(1, 1));
+    pixel.setFillColor(sf::Color(color.r << 3, color.g << 2, color.b << 3));
+    pixel.setPosition(x, y);
+    buffer.draw(pixel);
+}
+
+void Graphics::put_horizontal_line(uint16_t x, uint16_t x2, uint16_t y,
+                                   const Pixel &color)
+{
+    put_line(x, y, x2, y, color);
+}
+
+void Graphics::put_vertical_line(uint16_t x, uint16_t y, uint16_t y2, const Pixel &color)
+{
+    put_line(x, y, x, y2, color);
+}
+
+void Graphics::put_line(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2,
+                        const Pixel &color)
+{
+    sf::Color lineColor(color.r << 3, color.g << 2, color.b << 3);
+    sf::Vertex line[] = {sf::Vertex(sf::Vector2f(x, y), lineColor),
+                         sf::Vertex(sf::Vector2f(x2, y2), lineColor)};
+
+    buffer.draw(line, 2, sf::Lines);
+}
+
+void Graphics::put_rectangle(const Rect &rect, const Pixel &color)
+{
+    sf::RectangleShape rectangle;
+    rectangle.setSize(sf::Vector2f(rect.width, rect.height));
+    rectangle.setFillColor(sf::Color(color.r << 3, color.g << 2, color.b << 3));
+    rectangle.setPosition(rect.x, rect.y);
+    buffer.draw(rectangle);
 }

+ 61 - 16
platform/sfml/Input.cpp

@@ -1,35 +1,80 @@
 #include "Input.h"
+#include "Graphics.h" // window
 #include "sfwindow.h"
 #include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window.hpp>
 
 #define INPUT WalrusRPG::Input
+using WalrusRPG::Input::Key;
+using WalrusRPG::Input::KeyState;
+using sf::Keyboard;
 
-bool INPUT::key_a()
+struct InputMap
 {
-    return window.hasFocus() && sf::Keyboard::isKeyPressed(sf::Keyboard::Return);
-}
+    Key key;
+    sf::Keyboard::Key key_code;
+    sf::Keyboard::Key key_code_alt;
+};
+
+KeyState key_states[Key::K_SIZE] = {KeyState::KS_RELEASED};
+InputMap key_map[] = {
+    {Key::K_A, Keyboard::W, Keyboard::Z},
+    {Key::K_B, Keyboard::X, Keyboard::Unknown},
+    {Key::K_L, Keyboard::Q, Keyboard::A},
+    {Key::K_R, Keyboard::S, Keyboard::Unknown},
+
+    {Key::K_UP, Keyboard::Up, Keyboard::Unknown},
+    {Key::K_DOWN, Keyboard::Down, Keyboard::Unknown},
+    {Key::K_LEFT, Keyboard::Left, Keyboard::Unknown},
+    {Key::K_RIGHT, Keyboard::Right, Keyboard::Unknown},
+
+    {Key::K_START, Keyboard::Return, Keyboard::Unknown},
+    {Key::K_SELECT, Keyboard::BackSpace, Keyboard::Unknown},
+};
 
-bool INPUT::key_b()
+void INPUT::key_poll()
 {
-    return window.hasFocus() && sf::Keyboard::isKeyPressed(sf::Keyboard::BackSpace);
+    bool hasFocus = window.hasFocus();
+    for (unsigned i = 0; i < K_SIZE; i++)
+    {
+        bool current_key_state = hasFocus && Keyboard::isKeyPressed(key_map[i].key_code);
+        KeyState previous_key_state = key_states[i];
+
+        KeyState resulting_key_state = KS_RELEASED;
+        if (current_key_state)
+        {
+            if (previous_key_state == KS_RELEASED ||
+                previous_key_state == KS_JUST_RELEASED)
+                resulting_key_state = KS_JUST_PRESSED;
+            else if (previous_key_state == KS_JUST_PRESSED ||
+                     previous_key_state == KS_PRESSED)
+                resulting_key_state = KS_PRESSED;
+        }
+        else
+        {
+            if (previous_key_state == KS_PRESSED || previous_key_state == KS_JUST_PRESSED)
+                resulting_key_state = KS_JUST_RELEASED;
+            else if (previous_key_state == KS_JUST_RELEASED ||
+                     previous_key_state == KS_RELEASED)
+                resulting_key_state = KS_RELEASED;
+        }
+        key_states[i] = resulting_key_state;
+    }
 }
 
-bool INPUT::key_up()
+bool INPUT::key_pressed(Key key)
 {
-    return window.hasFocus() && sf::Keyboard::isKeyPressed(sf::Keyboard::W);
+    return key_states[key] == KS_JUST_PRESSED;
 }
-
-bool INPUT::key_down()
+bool INPUT::key_released(Key key)
 {
-    return window.hasFocus() && sf::Keyboard::isKeyPressed(sf::Keyboard::S);
+    return key_states[key] == KS_JUST_RELEASED;
 }
-
-bool INPUT::key_left()
+bool INPUT::key_down(Key key)
 {
-    return window.hasFocus() && sf::Keyboard::isKeyPressed(sf::Keyboard::A);
+    return key_states[key] == KS_JUST_PRESSED || key_states[key] == KS_PRESSED;
 }
-
-bool INPUT::key_right()
+bool INPUT::key_up(Key key)
 {
-    return window.hasFocus() && sf::Keyboard::isKeyPressed(sf::Keyboard::D);
+    return key_states[key] == KS_JUST_RELEASED || key_states[key] == KS_RELEASED;
 }

+ 26 - 2
platform/sfml/Texture.cpp

@@ -1,16 +1,40 @@
 #include "Texture.h"
 #include <SFML/Graphics/Texture.hpp>
 #include <SFML/OpenGL.hpp>
+#include <SFML/Graphics/Rect.hpp>
 #include <cstdint>
 #include "utility/misc.h"
+#include "render/Pixel.h"
 
 #define TEXTURE WalrusRPG::Graphics::Texture
 
+using WalrusRPG::Graphics::Pixel;
+
 TEXTURE::Texture(char *data) : data()
 {
-    UNUSED(data);
+    // UNUSED(data);
+    uint16_t *data_16 = (uint16_t *) data;
     // TOOD : load from PIAF
-    this->data.loadFromFile("art/overworld.png");
+    // this->data.loadFromFile("art/overworld.png");
+    // this->data.loadFromMemory(data+6, data_16[0]*data_16[1], sf::IntRect(0, 0,
+    // data_16[0], data_16[1]));
+    this->data.create(data_16[0], data_16[1]);
+    sf::Uint8 *pixels = new sf::Uint8[data_16[0] * data_16[1] * 4];
+    for (unsigned y = 0; y < data_16[1]; y++)
+    {
+        for (unsigned x = 0; x < data_16[0]; x++)
+        {
+            Pixel pix(data_16[3 + y * data_16[0] + x]);
+            unsigned pixel_offset = data_16[0] * y + x;
+            pixels[4 * pixel_offset] = pix.r << 3;
+            pixels[4 * pixel_offset + 1] = pix.g << 2;
+            pixels[4 * pixel_offset + 2] = pix.b << 3;
+            pixels[4 * pixel_offset + 3] = pix.value == data_16[2] ? 0 : 255;
+        }
+    }
+    this->data.update(pixels);
+
+    delete[] pixels;
 }
 
 TEXTURE::~Texture()

+ 3 - 1
platform/sfml/rules.mk

@@ -4,7 +4,9 @@ SRCS_C += $(wildcard $(sfml_LOCAL_PATH)/platform/*.c)
 SRCS_CPP += $(wildcard $(sfml_LOCAL_PATH)/*.cpp)
 INCLUDE += $(sfml_LOCAL_PATH)/public
 
-LDFLAGS += -lstdc++ -lsfml-window -lsfml-graphics -lsfml-system -lGL
+LDFLAGS += -lstdc++ -lsfml-window -lsfml-graphics -lsfml-system -lGL -lm
+
+CFLAGS_COMMON += -DSFML=1
 
 CC = gcc
 CPP = g++

+ 9 - 5
src/engine/StateMachine.cpp

@@ -9,6 +9,7 @@
 using namespace WalrusRPG::Graphics;
 using namespace WalrusRPG::States;
 using namespace WalrusRPG::Timing;
+using WalrusRPG::Input::Key;
 
 #define STATEMACHINE WalrusRPG::StateMachine
 
@@ -45,7 +46,8 @@ void STATEMACHINE::run()
     {
         update_stamp = Timing::gettime();
         update_time = update_stamp - last_update;
-        stack.back()->update(update_time);
+        Input::key_poll();
+        stack.back()->update(100 * update_time / TIMER_FREQ);
         last_update = update_stamp;
 
         if (Timing::gettime() < loop_next)
@@ -53,7 +55,7 @@ void STATEMACHINE::run()
             frame_stamp = Timing::gettime();
             frame_time = frame_stamp - last_frame;
             Graphics::frame_begin();
-            stack.back()->render(frame_time);
+            stack.back()->render(100 * frame_time / TIMER_FREQ);
             last_frame = frame_stamp;
 
             Text::print_format(0, 0, "WalrusRPG test build %s", git_version);
@@ -65,15 +67,17 @@ void STATEMACHINE::run()
             Graphics::frame_end();
         }
 
-        if (Input::key_b())
+        if (Input::key_pressed(Key::K_SELECT))
         {
-            while (Input::key_b())
-                ;
+            while (Input::key_down(Key::K_SELECT))
+                Input::key_poll();
             this->pop();
         }
 
+#ifdef ACTIVE_WAIT
         while (Timing::gettime() < loop_next)
             ;
+#endif
         loop_next += loop_time;
     }
 }

+ 4 - 4
src/engine/main.cpp

@@ -72,10 +72,10 @@ int main(int argc, char *argv[])
     Map map(20, 20, dungeonTest, dungeonTest2);
     tinystl::vector<Frame> stripe21;
     tinystl::vector<Frame> stripe22;
-    stripe21.push_back({21, 23 * 546});
-    stripe21.push_back({22, 31 * 546});
-    stripe22.push_back({22, 37 * 546});
-    stripe22.push_back({21, 41 * 546});
+    stripe21.push_back({21, 23});
+    stripe21.push_back({22, 31});
+    stripe22.push_back({22, 37});
+    stripe22.push_back({21, 41});
     map.anim.add_animation(21, {stripe21, true, 0});
     map.anim.add_animation(22, {stripe22, true, 0});
 

+ 5 - 4
src/render/Camera.cpp

@@ -5,6 +5,7 @@
 #define CAMERA WalrusRPG::Camera
 
 using namespace WalrusRPG;
+using WalrusRPG::Input::Key;
 
 CAMERA::Camera(signed x, signed y)
 {
@@ -30,13 +31,13 @@ void CAMERA::update(unsigned dt)
                 velocity += acceleration * dt;
          */
 
-    if (Input::key_down())
+    if (Input::key_down(Key::K_DOWN))
         y++;
-    if (Input::key_up())
+    if (Input::key_down(Key::K_UP))
         y--;
-    if (Input::key_right())
+    if (Input::key_down(Key::K_RIGHT))
         x++;
-    if (Input::key_left())
+    if (Input::key_down(Key::K_LEFT))
         x--;
 }
 

+ 6 - 1
src/render/Pixel.cpp

@@ -6,7 +6,7 @@ PIXEL::Pixel(std::uint16_t color) : value(color)
 {
 }
 
-PIXEL::Pixel(Pixel &pix) : value((std::uint8_t) pix)
+PIXEL::Pixel(Pixel &pix) : value(pix.value)
 {
 }
 
@@ -33,4 +33,9 @@ CONST_COLOR(White, 255, 255, 255);
 CONST_COLOR(Red, 255, 0, 0);
 CONST_COLOR(Green, 0, 255, 0);
 CONST_COLOR(Blue, 0, 0, 255);
+
+CONST_COLOR(Yellow, 255, 255, 0);
+CONST_COLOR(Cyan, 0, 255, 255);
+CONST_COLOR(Magenta, 255, 0, 255);
+
 #undef CONST_COLOR

+ 3 - 0
src/render/Pixel.h

@@ -43,6 +43,9 @@ namespace WalrusRPG
         extern const Pixel Red;
         extern const Pixel Green;
         extern const Pixel Blue;
+        extern const Pixel Yellow;
+        extern const Pixel Cyan;
+        extern const Pixel Magenta;
     }
 }
 

+ 7 - 0
src/render/SpriteRenderer.cpp

@@ -1,10 +1,12 @@
 #include <TINYSTL/unordered_map.h>
 #include "SpriteRenderer.h"
 #include "Graphics.h"
+#include "render/Pixel.h"
 
 #define SPRITERENDERER WalrusRPG::SpriteRenderer
 using namespace WalrusRPG;
 using namespace WalrusRPG::Utils;
+using WalrusRPG::Graphics::Pixel;
 
 SPRITERENDERER::SpriteRenderer(WalrusRPG::Graphics::Texture _tilesheet)
     : tilesheet(_tilesheet)
@@ -20,3 +22,8 @@ void SPRITERENDERER::render(const unsigned id, const Rect &rect)
 {
     Graphics::put_sprite(tilesheet, rect.x, rect.y, sprites[id]);
 }
+
+void SPRITERENDERER::render(const unsigned id, const Rect &rect, const Pixel& tint)
+{
+    Graphics::put_sprite_tint(tilesheet, rect.x, rect.y, sprites[id], tint);
+}

+ 1 - 0
src/render/SpriteRenderer.h

@@ -18,6 +18,7 @@ namespace WalrusRPG
         SpriteRenderer(WalrusRPG::Graphics::Texture tilesheet);
         void add_sprite(unsigned id, WalrusRPG::Utils::Rect rect);
         virtual void render(const unsigned id, const WalrusRPG::Utils::Rect &rect);
+        void render(const unsigned id, const WalrusRPG::Utils::Rect &rect, const WalrusRPG::Graphics::Pixel& tint);
     };
 }
 

+ 1 - 0
src/utility/misc.h

@@ -3,6 +3,7 @@
 
 #define UNUSED(expr) (void)(expr)
 
+#define abs(x) ((x) < 0 ? -(x) : (x))
 #define min(a, b) (((a) < (b)) ? (a) : (b))
 #define max(a, b) (((a) > (b)) ? (a) : (b))