Pārlūkot izejas kodu

Started windows support.

Florian "Eiyeron" Dormont 9 gadi atpakaļ
vecāks
revīzija
432a2a153f

+ 1 - 1
Makefile

@@ -14,7 +14,7 @@ CFLAGS = $(CFLAGS_COMMON) -std=gnu11
 
 CPPFLAGS = $(CFLAGS_COMMON) -std=gnu++11
 
-LDFLAGS = $(CFLAGS_COMMON) -fuse-ld=gold -lz
+LDFLAGS = $(CFLAGS_COMMON)  -lz
 
 SRCS_C :=
 SRCS_CPP :=

+ 1 - 1
mkconfig

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-TARGET_LIST=("nspire" "sfml")
+TARGET_LIST=("nspire" "sfml" "windows")
 
 create_configuration() {
 	echo "Creating $1 configuration"

+ 170 - 0
platform/windows/Graphics.cpp

@@ -0,0 +1,170 @@
+#include "Graphics.h"
+#include "Logger.h"
+#include "sfwindow.h"
+#include <SFML/Graphics.hpp>
+#include "utility/misc.h"
+#include "utility/minmax.h"
+
+using namespace WalrusRPG; /*::Graphics*/
+using WalrusRPG::Utils::Rect;
+
+sf::RenderWindow window;
+sf::View view;
+sf::RenderTexture buffer;
+
+
+void Graphics::init()
+{
+    Logger::log("Graphics init");
+    // 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()
+{
+    Logger::log("Graphics deinit");
+    window.close();
+}
+
+void Graphics::frame_begin()
+{
+    window.clear(sf::Color::Black);
+}
+
+void Graphics::frame_end()
+{
+    sf::Sprite sprite(buffer.getTexture());
+    sf::Vector2u winsize = window.getSize();
+    sf::Event event;
+    float scale = min(winsize.x / 320.f, winsize.y / 240.f);
+
+    while (window.pollEvent(event))
+    {
+    }
+
+    window.setView(view = sf::View(sf::FloatRect(0, 0, winsize.x, winsize.y)));
+
+    buffer.display();
+    window.clear();
+    sprite.setScale(scale, scale);
+    sprite.setPosition((winsize.x - 320.f * scale) / 2, (winsize.y - 240.f * scale) / 2);
+    window.draw(sprite);
+    window.display();
+}
+
+void Graphics::put_sprite(const Texture &sheet, int x, int y, const Rect &window)
+{
+    sf::Sprite sprite;
+    sprite.setTexture(sheet.data);
+    sprite.setTextureRect(sf::IntRect(window.x, window.y, window.width, window.height));
+    sprite.setPosition(x, y);
+    buffer.draw(sprite);
+}
+
+void Graphics::put_sprite_tint(const Texture &sheet, int x, int y, const Rect &window,
+                               const Pixel &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::put_sprite_clipping(const Texture &sheet, int x, int y,
+                                   const Rect &sprite_window, const Rect &clipping_window)
+{
+    const signed &ss_x = sprite_window.x, ss_y = sprite_window.y;
+    const signed &ss_w = sprite_window.width, &ss_h = sprite_window.height;
+    const signed &cx = clipping_window.x, &cy = clipping_window.y;
+    const signed &cw = clipping_window.width, &ch = clipping_window.height;
+    const signed lx = x - cx, ly = y - cy;
+
+    if (lx < -ss_w || lx > cw)
+        return;
+    if (ly < -ss_h || ly > ch)
+        return;
+
+    signed fx = x, fy = y;
+    signed fssx = ss_x, fssy = ss_y, fssw = ss_w, fssh = ss_h;
+
+    if (lx < 0)
+    {
+        fssw = ss_w + lx;
+        fssx = -lx;
+        fx = cx;
+    }
+
+    if (lx > cw - ss_w)
+    {
+        fssw -= lx - (cw - ss_w);
+    }
+
+    if (ly > ch - ss_h)
+    {
+        fssh -= ly - (ch - ss_h);
+    }
+
+    if (ly < 0)
+    {
+        fssh = ss_h + ly;
+        fssy = -ly;
+        fy = cy;
+    }
+
+    sf::Sprite sprite;
+    sprite.setTexture(sheet.data);
+    sprite.setTextureRect(sf::IntRect(fssx, fssy, fssw, fssh));
+    sprite.setPosition(fx, fy);
+    buffer.draw(sprite);
+}
+
+
+void Graphics::fill(const Pixel &color)
+{
+    buffer.clear(sf::Color(color.r << 3, color.g << 2, color.b << 3, 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, 255));
+    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_rectangle({x, y, x2 - x + 1u, 1}, color);
+}
+
+void Graphics::put_vertical_line(uint16_t x, uint16_t y, uint16_t y2, const Pixel &color)
+{
+    put_rectangle({x, y, 1, y2 - y + 1u}, 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, 255);
+    sf::Vertex line[] = {sf::Vertex(sf::Vector2f(x, y), lineColor),
+                         sf::Vertex(sf::Vector2f(x2 + 1, y2 + 1), 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, 255));
+    rectangle.setPosition(rect.x, rect.y);
+    buffer.draw(rectangle);
+}

+ 63 - 0
platform/windows/Logger.cpp

@@ -0,0 +1,63 @@
+#include "Logger.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+using namespace WalrusRPG;
+
+namespace
+{
+    // TODO : Find a better name
+    /**
+     * Prints the timestamp and the message category/type.
+     */
+    void print_premessage(const char *type)
+    {
+        char date_buffer[256];
+        time_t now = time(0);
+        strftime(date_buffer, 256, "%Y-%m-%d %H:%M:%S", localtime(&now));
+        printf("%s %5s : ", date_buffer, type);
+    }
+}
+
+// NOTE : I really wish there would be a better way to handle these stupid va_lists. So
+// much redundant code...
+
+void Logger::log(const char *fmt, ...)
+{
+    print_premessage("  [LOG]");
+    va_list args;
+    va_start(args, fmt);
+    vprintf(fmt, args);
+    va_end(args);
+    puts("");
+}
+
+void Logger::debug(const char *fmt, ...)
+{
+    print_premessage("[DEBUG]");
+    va_list args;
+    va_start(args, fmt);
+    vprintf(fmt, args);
+    va_end(args);
+    puts("");
+}
+
+void Logger::warn(const char *fmt, ...)
+{
+    print_premessage(" [WARN]");
+    va_list args;
+    va_start(args, fmt);
+    vprintf(fmt, args);
+    va_end(args);
+    puts("");
+}
+
+void Logger::error(const char *fmt, ...)
+{
+    print_premessage("[ERROR]");
+    va_list args;
+    va_start(args, fmt);
+    vprintf(fmt, args);
+    va_end(args);
+    puts("");
+}

+ 31 - 0
platform/windows/Quirks.cpp

@@ -0,0 +1,31 @@
+#include <cstring>
+#include "Quirks.h"
+#include "Logger.h"
+#include "utility/misc.h"
+#include "sfwindow.h"
+
+using namespace WalrusRPG;
+using tinystl::string;
+
+void Quirks::init(const char *argv_0)
+{
+    Logger::log("Quirks init");
+    UNUSED(argv_0);
+}
+
+void Quirks::deinit()
+{
+    Logger::log("Graphics deinit");
+}
+
+std::unique_ptr<char> Quirks::solve_absolute_path(const char *path)
+{
+    std::unique_ptr<char> result(new char[strlen(path) + 1]);
+    strcpy(result.get(), path);
+    return result;
+}
+
+bool Quirks::get_key(keycode_t key)
+{
+    return sf::Keyboard::isKeyPressed(key) && window.hasFocus();
+}

+ 61 - 0
platform/windows/Texture.cpp

@@ -0,0 +1,61 @@
+#include "Texture.h"
+#include <SFML/Graphics/Texture.hpp>
+#include <SFML/OpenGL.hpp>
+#include <SFML/Graphics/Rect.hpp>
+#include <cstdint>
+#include <cstdlib>
+#include "utility/misc.h"
+#include "render/Pixel.h"
+
+using namespace WalrusRPG::Graphics; /*Texture*/
+using WalrusRPG::Graphics::Pixel;
+using WalrusRPG::PIAF::File;
+using WalrusRPG::Utils::Rect;
+
+Texture::Texture(char *data) : data()
+{
+    uint16_t *data_16 = (uint16_t *) data;
+    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);
+
+    free(pixels);
+}
+
+Texture::Texture(WalrusRPG::PIAF::File entry) : data()
+{
+    // UNUSED(data);
+    // TOOD : load from PIAF
+    // this->data.loadFromFile("art/overworld.png");
+    this->data.loadFromMemory(entry.get(), entry.file_size);
+}
+
+Texture::~Texture()
+{
+}
+
+const Rect Texture::get_dimensions()
+{
+    sf::Vector2u size = data.getSize();
+    return {0, 0, size.x, size.y};
+}
+
+const Pixel Texture::get_pixel(unsigned x, unsigned y)
+{
+    UNUSED(x);
+    UNUSED(y);
+    // TODO : return the actual value
+    return {0};
+}

+ 23 - 0
platform/windows/Timing.cpp

@@ -0,0 +1,23 @@
+#include "Timing.h"
+#include "Logger.h"
+#include <SFML/System/Clock.hpp>
+#include <cstdio>
+
+using namespace WalrusRPG; /*Timing*/
+
+sf::Clock clock;
+
+void Timing::init()
+{
+    Logger::log("Timing init");
+}
+
+void Timing::deinit()
+{
+    Logger::log("Timing deinit");
+}
+
+unsigned Timing::gettime()
+{
+    return clock.getElapsedTime().asMicroseconds();
+}

+ 12 - 0
platform/windows/public/platform.h

@@ -0,0 +1,12 @@
+#ifndef INCLUDE_PLATFORM_H
+#define INCLUDE_PLATFORM_H
+
+#include <SFML/Graphics/Texture.hpp>
+#include <SFML/Window/Keyboard.hpp>
+
+#define TIMER_FREQ 1000000
+
+typedef sf::Texture texture_data_t;
+typedef sf::Keyboard::Key keycode_t;
+
+#endif

+ 22 - 0
platform/windows/rules.mk

@@ -0,0 +1,22 @@
+sfml_LOCAL_PATH := $(call whereami)
+
+SRCS_C += $(wildcard $(sfml_LOCAL_PATH)/platform/*.c)
+SRCS_CPP += $(wildcard $(sfml_LOCAL_PATH)/*.cpp)
+INCLUDE += $(sfml_LOCAL_PATH)/public
+
+LDFLAGS += -L/usr/lib -lstdc++ -lsfml-graphics -lsfml-window -lsfml-system -lopengl32 -lwinmm -lgdi32 -lm
+
+CFLAGS_COMMON += -DTARGET_WINDOWS=1 -mwindows
+
+INCLUDE_EXT += /usr/include
+
+CC = mingw32-gcc
+CPP = mingw32-g++
+
+EXE = $(OUT)/$(NAME).exe
+
+$(EXE): $(ELF)
+	@cp $(ELF) $(EXE)
+
+run: all
+	./$(EXE)

+ 8 - 0
platform/windows/sfwindow.h

@@ -0,0 +1,8 @@
+#ifndef INCLUDE_SFWINDOW_H
+#define INCLUDE_SFWINDOW_H
+
+#include <SFML/Graphics/RenderWindow.hpp>
+
+extern sf::RenderWindow window;
+
+#endif

+ 1 - 1
rules.mk

@@ -33,7 +33,7 @@ $(OUT)/%.o: %.cpp | $(BUILT_SRCS)
 $(ELF): $(OBJS)
 	@mkdir -p $(dir $@)
 	@echo "CCLD: $@"
-	@+$(CC) $(LDFLAGS) $^ -o $(ELF)
+	@+$(CC) $^ -o $(ELF) $(LDFLAGS)
 
 clean:
 	@echo "RM: $(OUT)"

+ 1 - 1
src/input/Input.cpp

@@ -20,7 +20,7 @@ struct KeyBuffer
 struct KeyBuffer key_states[Key::K_SIZE] = {{false, false}};
 
 // TODO: make these software-mappable
-#ifdef TARGET_SFML
+#if defined(TARGET_SFML) || defined(TARGET_WINDOWS)
 using sf::Keyboard;
 InputMap key_map[] = {
     {Key::K_A, Keyboard::W},          {Key::K_B, Keyboard::X},

+ 1 - 1
src/piaf/Exceptions.cpp

@@ -8,7 +8,7 @@ using WalrusRPG::PIAF::PIAFException;
 using namespace WalrusRPG::PIAF;
 using namespace WalrusRPG::Logger;
 
-PIAFException::PIAFException(const char *format, ...) : msg("")
+PIAFException::PIAFException(const char *format, ...) : msg{0}
 {
     va_list list;
     va_start(list, format);