瀏覽代碼

Import meta ball visualizer project

DricomDragon 4 年之前
父節點
當前提交
3b68286506

+ 1 - 0
sdl2/metaBallsVisualizer/.gitignore

@@ -0,0 +1 @@
+MetaBallVisualizer

+ 23 - 0
sdl2/metaBallsVisualizer/CMakeLists.txt

@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.7)
+project(MetaBallVisualizer)
+
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CmakeFinders")
+
+find_package(SDL2)
+find_package(SDL2_ttf)
+
+include_directories(${SDL2_INCLUDE_DIR} ${SDL2_TTF_INCLUDE_DIRS})
+
+set(CMAKE_CXX_STANDARD 11)
+
+set(SOURCE_FILES
+        main.cpp
+        GameCore.cpp
+        Control/Input.cpp
+        Graphics/MetaField.cpp
+        Graphics/Renderer.cpp
+        constantes.h)
+
+add_executable(MetaBallVisualizer ${SOURCE_FILES})
+
+target_link_libraries(MetaBallVisualizer ${SDL2_LIBRARY} ${SDL2_TTF_LIBRARIES})

+ 173 - 0
sdl2/metaBallsVisualizer/CmakeFinders/FindSDL2.cmake

@@ -0,0 +1,173 @@
+
+# This module defines
+# SDL2_LIBRARY, the name of the library to link against
+# SDL2_FOUND, if false, do not try to link to SDL2
+# SDL2_INCLUDE_DIR, where to find SDL.h
+#
+# This module responds to the the flag:
+# SDL2_BUILDING_LIBRARY
+# If this is defined, then no SDL2main will be linked in because
+# only applications need main().
+# Otherwise, it is assumed you are building an application and this
+# module will attempt to locate and set the the proper link flags
+# as part of the returned SDL2_LIBRARY variable.
+#
+# Don't forget to include SDLmain.h and SDLmain.m your project for the
+# OS X framework based version. (Other versions link to -lSDL2main which
+# this module will try to find on your behalf.) Also for OS X, this
+# module will automatically add the -framework Cocoa on your behalf.
+#
+#
+# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration
+# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library
+# (SDL2.dll, libsdl2.so, SDL2.framework, etc).
+# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again.
+# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value
+# as appropriate. These values are used to generate the final SDL2_LIBRARY
+# variable, but when these values are unset, SDL2_LIBRARY does not get created.
+#
+#
+# $SDL2DIR is an environment variable that would
+# correspond to the ./configure --prefix=$SDL2DIR
+# used in building SDL2.
+# l.e.galup  9-20-02
+#
+# Modified by Eric Wing.
+# Added code to assist with automated building by using environmental variables
+# and providing a more controlled/consistent search behavior.
+# Added new modifications to recognize OS X frameworks and
+# additional Unix paths (FreeBSD, etc).
+# Also corrected the header search path to follow "proper" SDL guidelines.
+# Added a search for SDL2main which is needed by some platforms.
+# Added a search for threads which is needed by some platforms.
+# Added needed compile switches for MinGW.
+#
+# On OSX, this will prefer the Framework version (if found) over others.
+# People will have to manually change the cache values of
+# SDL2_LIBRARY to override this selection or set the CMake environment
+# CMAKE_INCLUDE_PATH to modify the search paths.
+#
+# Note that the header path has changed from SDL2/SDL.h to just SDL.h
+# This needed to change because "proper" SDL convention
+# is #include "SDL.h", not <SDL2/SDL.h>. This is done for portability
+# reasons because not all systems place things in SDL2/ (see FreeBSD).
+
+#=============================================================================
+# Copyright 2003-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# message("<FindSDL2.cmake>")
+
+SET(SDL2_SEARCH_PATHS
+	~/Library/Frameworks
+	/Library/Frameworks
+	/usr/local
+	/usr
+	/sw # Fink
+	/opt/local # DarwinPorts
+	/opt/csw # Blastwave
+	/opt
+	${SDL2_PATH}
+)
+
+FIND_PATH(SDL2_INCLUDE_DIR SDL.h
+	HINTS
+	$ENV{SDL2DIR}
+	PATH_SUFFIXES include/SDL2 include
+	PATHS ${SDL2_SEARCH_PATHS}
+)
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8) 
+	set(PATH_SUFFIXES lib64 lib/x64 lib)
+else() 
+	set(PATH_SUFFIXES lib/x86 lib)
+endif() 
+
+FIND_LIBRARY(SDL2_LIBRARY_TEMP
+	NAMES SDL2
+	HINTS
+	$ENV{SDL2DIR}
+	PATH_SUFFIXES ${PATH_SUFFIXES}
+	PATHS ${SDL2_SEARCH_PATHS}
+)
+
+IF(NOT SDL2_BUILDING_LIBRARY)
+	IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
+		# Non-OS X framework versions expect you to also dynamically link to
+		# SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms
+		# seem to provide SDL2main for compatibility even though they don't
+		# necessarily need it.
+		FIND_LIBRARY(SDL2MAIN_LIBRARY
+			NAMES SDL2main
+			HINTS
+			$ENV{SDL2DIR}
+			PATH_SUFFIXES ${PATH_SUFFIXES}
+			PATHS ${SDL2_SEARCH_PATHS}
+		)
+	ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework")
+ENDIF(NOT SDL2_BUILDING_LIBRARY)
+
+# SDL2 may require threads on your system.
+# The Apple build may not need an explicit flag because one of the
+# frameworks may already provide it.
+# But for non-OSX systems, I will use the CMake Threads package.
+IF(NOT APPLE)
+	FIND_PACKAGE(Threads)
+ENDIF(NOT APPLE)
+
+# MinGW needs an additional link flag, -mwindows
+# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows
+IF(MINGW)
+	SET(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "mwindows for MinGW")
+ENDIF(MINGW)
+
+IF(SDL2_LIBRARY_TEMP)
+	# For SDL2main
+	IF(NOT SDL2_BUILDING_LIBRARY)
+		IF(SDL2MAIN_LIBRARY)
+			SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP})
+		ENDIF(SDL2MAIN_LIBRARY)
+	ENDIF(NOT SDL2_BUILDING_LIBRARY)
+
+	# For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa.
+	# CMake doesn't display the -framework Cocoa string in the UI even
+	# though it actually is there if I modify a pre-used variable.
+	# I think it has something to do with the CACHE STRING.
+	# So I use a temporary variable until the end so I can set the
+	# "real" variable in one-shot.
+	IF(APPLE)
+		SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa")
+	ENDIF(APPLE)
+
+	# For threads, as mentioned Apple doesn't need this.
+	# In fact, there seems to be a problem if I used the Threads package
+	# and try using this line, so I'm just skipping it entirely for OS X.
+	IF(NOT APPLE)
+		SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT})
+	ENDIF(NOT APPLE)
+
+	# For MinGW library
+	IF(MINGW)
+		SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP})
+	ENDIF(MINGW)
+
+	# Set the final string here so the GUI reflects the final state.
+	SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found")
+	# Set the temp variable to INTERNAL so it is not seen in the CMake GUI
+	SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "")
+ENDIF(SDL2_LIBRARY_TEMP)
+
+# message("</FindSDL2.cmake>")
+
+INCLUDE(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)

+ 98 - 0
sdl2/metaBallsVisualizer/CmakeFinders/FindSDL2_ttf.cmake

@@ -0,0 +1,98 @@
+# Locate SDL_ttf library
+#
+# This module defines:
+#
+# ::
+#
+#   SDL2_TTF_LIBRARIES, the name of the library to link against
+#   SDL2_TTF_INCLUDE_DIRS, where to find the headers
+#   SDL2_TTF_FOUND, if false, do not try to link against
+#   SDL2_TTF_VERSION_STRING - human-readable string containing the version of SDL_ttf
+#
+#
+#
+# For backward compatibility the following variables are also set:
+#
+# ::
+#
+#   SDLTTF_LIBRARY (same value as SDL2_TTF_LIBRARIES)
+#   SDLTTF_INCLUDE_DIR (same value as SDL2_TTF_INCLUDE_DIRS)
+#   SDLTTF_FOUND (same value as SDL2_TTF_FOUND)
+#
+#
+#
+# $SDLDIR is an environment variable that would correspond to the
+# ./configure --prefix=$SDLDIR used in building SDL.
+#
+# Created by Eric Wing.  This was influenced by the FindSDL.cmake
+# module, but with modifications to recognize OS X frameworks and
+# additional Unix paths (FreeBSD, etc).
+
+#=============================================================================
+# Copyright 2005-2009 Kitware, Inc.
+# Copyright 2012 Benjamin Eikel
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+find_path(SDL2_TTF_INCLUDE_DIR SDL_ttf.h
+        HINTS
+        ENV SDL2TTFDIR
+        ENV SDL2DIR
+        PATH_SUFFIXES SDL2
+        # path suffixes to search inside ENV{SDLDIR}
+        include/SDL2 include
+        PATHS ${SDL2_TTF_PATH}
+        )
+
+if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(VC_LIB_PATH_SUFFIX lib/x64)
+else ()
+    set(VC_LIB_PATH_SUFFIX lib/x86)
+endif ()
+
+find_library(SDL2_TTF_LIBRARY
+        NAMES SDL2_ttf
+        HINTS
+        ENV SDL2TTFDIR
+        ENV SDL2DIR
+        PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
+        PATHS ${SDL2_TTF_PATH}
+        )
+
+if (SDL2_TTF_INCLUDE_DIR AND EXISTS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h")
+    file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_TTF_INCLUDE_DIR}/SDL_ttf.h" SDL2_TTF_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+[0-9]+$")
+    string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MAJOR "${SDL2_TTF_VERSION_MAJOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_TTF_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_MINOR "${SDL2_TTF_VERSION_MINOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_TTF_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_TTF_VERSION_PATCH "${SDL2_TTF_VERSION_PATCH_LINE}")
+    set(SDL2_TTF_VERSION_STRING ${SDL2_TTF_VERSION_MAJOR}.${SDL2_TTF_VERSION_MINOR}.${SDL2_TTF_VERSION_PATCH})
+    unset(SDL2_TTF_VERSION_MAJOR_LINE)
+    unset(SDL2_TTF_VERSION_MINOR_LINE)
+    unset(SDL2_TTF_VERSION_PATCH_LINE)
+    unset(SDL2_TTF_VERSION_MAJOR)
+    unset(SDL2_TTF_VERSION_MINOR)
+    unset(SDL2_TTF_VERSION_PATCH)
+endif ()
+
+set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY})
+set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_ttf
+        REQUIRED_VARS SDL2_TTF_LIBRARIES SDL2_TTF_INCLUDE_DIRS
+        VERSION_VAR SDL2_TTF_VERSION_STRING)
+
+# for backward compatibility
+set(SDLTTF_LIBRARY ${SDL2_TTF_LIBRARIES})
+set(SDLTTF_INCLUDE_DIR ${SDL2_TTF_INCLUDE_DIRS})
+set(SDLTTF_FOUND ${SDL2_TTF_FOUND})

+ 166 - 0
sdl2/metaBallsVisualizer/Control/Input.cpp

@@ -0,0 +1,166 @@
+#include "Input.h"
+
+
+// Constructor
+Input::Input()
+        : m_x(0), m_y(0), m_xRel(0), m_yRel(0),
+          m_finished(false), m_relativeMouse(false), m_window(0), m_windowHalfHeight(0), m_windowHalfWidth(0) {
+    // Initialisation du tableau m_keys[]
+    for (int i(0); i < SDL_NUM_SCANCODES; i++)
+        m_keys[i] = false;
+
+    // Initialisation du tableau m_mouseKeys[]
+    for (int i(0); i < 8; i++)
+        m_mouseKeys[i] = false;
+}
+
+// Destructor
+Input::~Input() {}
+
+
+// Methods
+void Input::updateEvents() {
+    // Reset relative coordinates
+    m_xRel = 0;
+    m_yRel = 0;
+
+    // Clear instant keys
+    m_instantKeys.clear();
+
+    // Event loop
+    while (SDL_PollEvent(&m_event)) {
+        if (catchKeyBoardEvents(m_event))
+            continue;
+        else if (catchMouseEvents(m_event))
+            continue;
+        else
+            catchWindowEvents(m_event);
+    }
+
+    // Keeping mouse in window
+    if (m_relativeMouse)
+        SDL_WarpMouseInWindow(m_window, m_windowHalfWidth, m_windowHalfHeight);
+}
+
+bool Input::catchKeyBoardEvents(const SDL_Event &event) {
+    switch (event.type) {
+        case SDL_KEYDOWN:
+            m_keys[event.key.keysym.scancode] = true;
+            m_instantKeys.insert(event.key.keysym.scancode);
+            return true;
+        case SDL_KEYUP:
+            m_keys[event.key.keysym.scancode] = false;
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool Input::catchMouseEvents(const SDL_Event &event) {
+    switch (event.type) {
+        case SDL_MOUSEBUTTONDOWN:
+            m_mouseKeys[event.button.button] = true;
+            return true;
+        case SDL_MOUSEBUTTONUP:
+            m_mouseKeys[event.button.button] = false;
+            return true;
+        case SDL_MOUSEMOTION:
+            if (m_relativeMouse) {
+                m_xRel = event.motion.x - m_windowHalfWidth;
+                m_yRel = event.motion.y - m_windowHalfHeight;
+            } else {
+                m_x = event.motion.x;
+                m_y = event.motion.y;
+                m_xRel = event.motion.xrel;
+                m_yRel = event.motion.yrel;
+            }
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool Input::catchWindowEvents(const SDL_Event &event) {
+    switch (event.type) {
+        case SDL_WINDOWEVENT:
+            if (event.window.event == SDL_WINDOWEVENT_CLOSE)
+                m_finished = true;
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool Input::isFinished() const {
+    return m_finished;
+}
+
+
+void Input::showCursor(bool flag) const {
+    if (flag)
+        SDL_ShowCursor(SDL_ENABLE);
+    else
+        SDL_ShowCursor(SDL_DISABLE);
+}
+
+
+void Input::capPtr(bool flag) {
+    m_relativeMouse = flag;
+}
+
+
+// Getters
+bool Input::getKey(const SDL_Scancode key) const {
+    return m_keys[key];
+}
+
+bool Input::getInstantKey(const SDL_Scancode key) const {
+    return m_instantKeys.find(key) != m_instantKeys.end();
+}
+
+bool Input::getMouseKey(const Uint8 key) const {
+    return m_mouseKeys[key];
+}
+
+
+bool Input::isMouseMoving() const {
+    return !(m_xRel == 0 && m_yRel == 0);
+}
+
+
+// Getters upon cursor position
+int Input::getX() const {
+    return m_x;
+}
+
+int Input::getY() const {
+    return m_y;
+}
+
+int Input::getXFromCenter() {
+    return m_x - m_windowHalfWidth;
+}
+
+int Input::getYFromCenter() {
+    return m_y - m_windowHalfHeight;
+}
+
+int Input::getXRel() const {
+    return m_xRel;
+}
+
+int Input::getYRel() const {
+    return m_yRel;
+}
+
+void Input::setWindow(SDL_Window *activWindow) {
+    // Direct relation
+    m_window = activWindow;
+
+    // Middle computation
+    SDL_GetWindowSize(activWindow, &m_windowHalfWidth, &m_windowHalfHeight);
+    m_windowHalfWidth /= 2;
+    m_windowHalfHeight /= 2;
+}
+
+

+ 85 - 0
sdl2/metaBallsVisualizer/Control/Input.h

@@ -0,0 +1,85 @@
+#ifndef DEF_INPUT
+#define DEF_INPUT
+
+///Jovian
+///Centralisation du traitement d'évènement
+
+// Include
+#include <set>
+#include <SDL.h>
+
+#define MOUSE_LEFT 1
+#define MOUSE_MIDDLE 2
+#define MOUSE_RIGHT 3
+#define MOUSE_ANNEX_A 4
+#define MOUSE_ANNEX_B 5
+
+class Input {
+    /// Methods
+public:
+
+    Input();
+
+    virtual ~Input();
+
+    virtual void updateEvents();
+
+protected: // Deal with an event, return true if caught
+    bool catchKeyBoardEvents(const SDL_Event &event);
+
+    bool catchMouseEvents(const SDL_Event &event);
+
+    bool catchWindowEvents(const SDL_Event &event);
+
+public:
+    bool isFinished() const;
+
+    void showCursor(bool flag) const;
+
+    void capPtr(bool flag);
+
+    bool getKey(const SDL_Scancode key) const;
+
+    bool getInstantKey(const SDL_Scancode key) const;
+
+    bool getMouseKey(const Uint8 key) const;
+
+    bool isMouseMoving() const;
+
+    int getX() const;
+
+    int getY() const;
+
+    int getXFromCenter();
+
+    int getYFromCenter();
+
+    int getXRel() const;
+
+    int getYRel() const;
+
+    void setWindow(SDL_Window *activWindow);
+
+    /// Variables
+protected:
+
+    SDL_Event m_event;
+    bool m_keys[SDL_NUM_SCANCODES];
+    std::set<SDL_Scancode> m_instantKeys;
+    bool m_mouseKeys[8];
+
+    int m_x;
+    int m_y;
+    int m_xRel;
+    int m_yRel;
+
+    bool m_finished;
+    bool m_relativeMouse;
+
+    SDL_Window *m_window;
+    int m_windowHalfHeight;
+    int m_windowHalfWidth;
+};
+
+#endif
+

+ 96 - 0
sdl2/metaBallsVisualizer/GameCore.cpp

@@ -0,0 +1,96 @@
+//
+// Created by jovian on 18/07/17.
+//
+
+// Basics
+#include <iostream>
+#include "GameCore.h"
+#include "Graphics/MetaField.h"
+
+GameCore::GameCore()
+        : m_input(nullptr), m_rend(nullptr) {}
+
+GameCore::~GameCore() {
+    // Input
+    if (m_input != nullptr) {
+        delete m_input;
+        m_input = nullptr;
+    }
+
+    // Destroy SDL renderer
+    if (m_rend != nullptr) {
+        delete m_rend;
+        m_rend = nullptr;
+    }
+}
+
+bool GameCore::initialize() {
+    // Already initialized
+    if (m_input != nullptr)
+        return false;
+
+    // Error check
+    bool okay(true);
+
+    // Create display
+    m_rend = new Renderer;
+    okay = okay && m_rend->initialize();
+
+    // Create hardware interface
+    m_input = new Input;
+    m_input->setWindow(m_rend->getWindow());
+
+    // End
+    return okay;
+}
+
+void GameCore::start() {
+    // Time
+    Uint32 frameRate(60); // Frame per second
+    Uint32 prevTime(0); // Previous chrono
+    Uint32 waitTime(1000 / frameRate); // Time to wait between each frame
+    Uint32 osBuffer(4); // To prevent SDL_Delay mistake : high > less mistake, more CPU usage
+
+    // Matrix field
+    bool field[WIN_H][WIN_W];
+    MetaField meta;
+    std::vector<MetaBall> balls;
+
+    // Main loop
+    while (!m_input->isFinished() && !m_input->getKey(SDL_SCANCODE_ESCAPE)) {
+        // Update events
+        m_input->updateEvents();
+
+        // Rendering
+        m_rend->clearWindow();
+
+        meta.clean();
+
+        if (m_input->getInstantKey(SDL_SCANCODE_E))
+            balls.push_back({m_input->getX(), m_input->getY(), 1000.0});
+
+        for (auto b : balls)
+            meta.disturb(b.y, b.x, b.power);
+
+        meta.disturb(m_input->getY(), m_input->getX(), 1000.0);
+
+        meta.binary(field, 1.0);
+
+        m_rend->renderBoolMatrix(field);
+
+        m_rend->presentWindow();
+
+        // todo Remove debug
+        /*Uint32 debug_conso(SDL_GetTicks() - prevTime);
+        std::cout << "Time use : " << debug_conso << std::endl;*/
+
+        // Pause
+        if (SDL_GetTicks() + osBuffer < prevTime + waitTime)
+            SDL_Delay(waitTime + prevTime - SDL_GetTicks() - osBuffer);
+
+        while (SDL_GetTicks() < prevTime + waitTime) {}
+
+        prevTime = SDL_GetTicks();
+    }
+}
+

+ 29 - 0
sdl2/metaBallsVisualizer/GameCore.h

@@ -0,0 +1,29 @@
+//
+// Created by jovian on 18/07/17.
+//
+
+#ifndef TINYSHOOTER_GAMECORE_H
+#define TINYSHOOTER_GAMECORE_H
+
+// Read hardware commands
+#include "Control/Input.h"
+
+// For game display
+#include "Graphics/Renderer.h"
+#include "Graphics/MetaField.h"
+
+class GameCore {
+public :
+    GameCore();
+    virtual ~GameCore();
+
+    bool initialize(); // Create attributes, return false if failure occurred
+    void start(); // Start a default game
+
+protected:
+    Input *m_input;
+    Renderer *m_rend;
+};
+
+
+#endif //TINYSHOOTER_GAMECORE_H

+ 35 - 0
sdl2/metaBallsVisualizer/Graphics/MetaField.cpp

@@ -0,0 +1,35 @@
+//
+// Created by jovian on 09/10/17.
+//
+
+#include "MetaField.h"
+
+MetaField::MetaField() {
+    clean();
+}
+
+void MetaField::clean() {
+    for (int i(0); i < WIN_H; i++)
+        for (int j(0); j < WIN_W; j++) {
+            m_field[i][j] = 0.0;
+        }
+}
+
+void MetaField::binary(bool mat[WIN_H][WIN_W], float ceil) {
+    for (int i(0); i < WIN_H; i++)
+        for (int j(0); j < WIN_W; j++) {
+            mat[i][j] = (m_field[i][j] > ceil);
+        }
+}
+
+void MetaField::disturb(int y, int x, float weight) {
+    // Escape
+    if (x < 0 || x >= WIN_W || y < 0 || y >= WIN_H)
+        return;
+
+    // todo Disturb
+    for (int i(0); i < WIN_H; i++)
+        for (int j(0); j < WIN_W; j++) {
+            m_field[i][j] += weight / ((y - i)*(y - i) + (x - j)*(x - j));
+        }
+}

+ 31 - 0
sdl2/metaBallsVisualizer/Graphics/MetaField.h

@@ -0,0 +1,31 @@
+//
+// Created by jovian on 09/10/17.
+//
+
+#ifndef METABALLVISUALIZER_METAFIELD_H
+#define METABALLVISUALIZER_METAFIELD_H
+
+#include "../constantes.h"
+
+struct MetaBall
+{
+    int x;
+    int y;
+    float power;
+};
+
+
+class MetaField {
+public:
+    MetaField();
+
+    void clean();
+    void binary(bool mat[WIN_H][WIN_W], float ceil);
+    void disturb(int y, int x, float weight = 1.0);
+
+protected:
+    float m_field[WIN_H][WIN_W];
+};
+
+
+#endif //METABALLVISUALIZER_METAFIELD_H

+ 314 - 0
sdl2/metaBallsVisualizer/Graphics/Renderer.cpp

@@ -0,0 +1,314 @@
+//
+// Created by jovian on 18/07/17.
+//
+
+#include <iostream>
+#include "Renderer.h"
+
+
+#define RAD_TO_DEG 57.2957795130f
+
+Renderer::Renderer()
+        : m_screenWidth(0), m_screenHeight(0), m_window(nullptr), m_renderer(nullptr), m_font(nullptr) {}
+
+Renderer::~Renderer() {
+    // Destroy textures
+    while (!m_pictureTab.empty()) {
+        if (m_pictureTab.back() != nullptr)
+            SDL_DestroyTexture(m_pictureTab.back());
+        m_pictureTab.pop_back();
+    }
+
+    // Destroy string textures
+    for (auto it(m_stringTab.begin()); it != m_stringTab.end(); it++) {
+        if (it->second != nullptr)
+            SDL_DestroyTexture(it->second);
+
+        it->second = nullptr;
+    }
+    m_stringTab.clear();
+
+    // Destroy SDL renderer
+    if (m_renderer != nullptr) {
+        SDL_DestroyRenderer(m_renderer);
+        m_renderer = nullptr;
+    }
+
+    // Destroy the beautiful window
+    if (m_window != nullptr) {
+        SDL_DestroyWindow(m_window);
+        m_window = nullptr;
+    }
+
+    // Quit modules
+    TTF_Quit();
+    SDL_Quit();
+}
+
+bool Renderer::initialize() {
+    // Announce
+    std::cout << "Renderer::initialize() > ";
+
+    // Already initialized
+    if (m_window != nullptr) {
+        std::cout << "Window already created." << std::endl << std::endl;
+        return false;
+    }
+
+    // Default screen size
+    m_screenWidth = WIN_W;
+    m_screenHeight = WIN_H;
+
+    // Init video
+    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
+        std::cout << "SDL video failed : " << SDL_GetError() << std::endl << std::endl;
+        return false;
+    }
+
+    // Init font
+    if (TTF_Init() == -1) {
+        std::cout << "TTF failed : " << TTF_GetError() << std::endl << std::endl;
+        return false;
+    }
+
+    m_font = TTF_OpenFont("droid.ttf", 28);
+    if (m_font == NULL) {
+        std::cout << "Open droid.ttf failed : " << TTF_GetError() << std::endl << std::endl;
+        return false;
+    }
+
+    // Opening window
+    m_window = SDL_CreateWindow("MetaBalls visualizer - Jovian Hersemeule",
+                                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
+                                m_screenWidth, m_screenHeight,
+                                SDL_WINDOW_SHOWN /*| SDL_WINDOW_FULLSCREEN_DESKTOP*/);
+    if (m_window == nullptr) {
+        std::cout << "Window creation failed : " << SDL_GetError() << std::endl << std::endl;
+        SDL_Quit();
+        return false;
+    }
+
+    // Hardware physical screen size
+    SDL_GetWindowSize(m_window, &m_screenWidth, &m_screenHeight);
+
+    // Create renderer
+    m_renderer = SDL_CreateRenderer(m_window, -1,
+                                    SDL_RENDERER_ACCELERATED |
+                                    SDL_RENDERER_PRESENTVSYNC);
+    if (m_renderer == nullptr) {
+        SDL_DestroyWindow(m_window);
+        std::cout << "SDL Renderer creation failed : " << SDL_GetError() << std::endl << std::endl;
+        SDL_Quit();
+        return false;
+    }
+
+    // End
+    std::cout << "Done, no error detected." << std::endl;
+
+    // Okay
+    return true;
+}
+
+void Renderer::clearWindow() {
+    // Clean up buffer
+    SDL_SetRenderDrawColor(m_renderer, 0x00, 0x00, 0x00, 0x00);
+    SDL_RenderClear(m_renderer);
+}
+
+/*void Renderer::renderScene(std::vector<Visual *> &scope, const b2Vec2 &center, float zoom) {
+    // Texture existence
+    if (m_pictureTab.empty())
+        return;
+
+    // Rect
+    SDL_Rect dst;
+    SDL_Texture *tex;
+    b2Vec2 rel;
+    float localZoom;
+
+    // For each
+    for (auto it(scope.begin()); it != scope.end(); it++) {
+        // Skip if no invalid texture
+        if ((*it)->getImgId() > m_pictureTab.size() || m_pictureTab[(*it)->getImgId()] == nullptr)
+            tex = m_pictureTab[0];
+        else
+            tex = m_pictureTab[(*it)->getImgId()];
+
+        // Adjusting local zoom
+        localZoom = zoom * (*it)->getScale();
+
+        // Rect set up
+        rel = (*it)->getPos() - center;
+        dst.x = (int) (rel.x * zoom) + m_screenWidth / 2;
+        dst.y = (int) (rel.y * zoom) + m_screenHeight / 2;
+        SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);
+
+        // Zoom correction
+        dst.w = (int) (localZoom * dst.w / DEFAULT_ZOOM);
+        dst.h = (int) (localZoom * dst.h / DEFAULT_ZOOM);
+
+        // Center texture
+        dst.x -= dst.w / 2;
+        dst.y -= dst.h / 2;
+
+        // SDL rendering
+        SDL_RenderCopyEx(m_renderer, tex, NULL, &dst, (*it)->getAngle() * RAD_TO_DEG, NULL, SDL_FLIP_NONE);
+    }
+
+}*/
+
+/*void Renderer::renderPlanetHUD(PlanetDef def) {
+    // Variable
+    SDL_Rect dst;
+
+    // Line under color
+    const Uint8 uncl(0xaf);
+
+    // Render rect
+    dst.x = 10;
+    dst.y = 10;
+    int w = m_screenWidth / 2 - 2*dst.x + 24;
+    int h = m_screenHeight * 2 / 3 - 2*dst.y;
+    dst.w = w;
+    dst.h = h;
+
+    SDL_SetRenderDrawColor(m_renderer, 0x66, 0x66, 0x66, 0xff);
+    SDL_RenderFillRect(m_renderer, &dst);
+
+    SDL_SetRenderDrawColor(m_renderer, 0xff, 0xff, 0xff, 0xff);
+    SDL_RenderDrawRect(m_renderer, &dst);
+    SDL_RenderDrawLine(m_renderer, dst.x, dst.y + 37, dst.x + dst.w - 1, dst.y + 37);
+
+    // Render planet name
+    dst.x = 11;
+    dst.y = 11;
+    renderName(dst, def.name);
+
+    // Column
+    dst.x = 20;
+
+    // Jumps
+#define H_NEXT_BAR 32
+#define H_OFFSET_BAR 10
+
+    // People
+    dst.y = 60;
+    SDL_SetRenderDrawColor(m_renderer, uncl, uncl, uncl, 0xff);
+    SDL_RenderDrawLine(m_renderer, dst.x, dst.y + H_OFFSET_BAR + 8, dst.x + w - 12, dst.y + H_OFFSET_BAR + 8);
+    renderName(dst, "People");
+    renderBar(dst.y + H_OFFSET_BAR, def.stock.get(PEOPLE));
+}*/
+
+void Renderer::renderName(SDL_Rect &dst, std::string name) {
+    // Seek an existing name texture
+    auto it(m_stringTab.find(name));
+
+    if (it == m_stringTab.end()) {
+        // Not loaded yet, let's fix this !
+        if (!loadStringTexture(name))
+            return;
+
+        SDL_QueryTexture(m_stringTab[name], NULL, NULL, &dst.w, &dst.h);
+        SDL_RenderCopy(m_renderer, m_stringTab[name], NULL, &dst);
+    } else {
+        // Faster plot
+        SDL_QueryTexture(it->second, NULL, NULL, &dst.w, &dst.h);
+        SDL_RenderCopy(m_renderer, it->second, NULL, &dst);
+    }
+}
+
+void Renderer::renderBoolMatrix(bool mat[WIN_H][WIN_W]) {
+    SDL_SetRenderDrawColor(m_renderer, 255, 255, 0, 255);
+
+    std::vector<SDL_Point> points;
+
+    for (int i(0); i < WIN_H; i++)
+        for (int j(0); j < WIN_W; j++) {
+            if (mat[i][j])
+                //SDL_RenderDrawPoint(m_renderer, j, i);
+                points.push_back({j, i});
+        }
+
+    SDL_RenderDrawPoints(m_renderer, points.data(), (int)points.size());
+}
+
+
+/*void Renderer::renderBar(int y, const int &value) {
+    // Set position
+    SDL_Rect dst;
+    dst.x = 208;
+    dst.y = y;
+    dst.h = 16;
+
+    // Set color and scale
+    if (value == 0) {
+        SDL_SetRenderDrawColor(m_renderer, 0x00, 0x00, 0x00, 0xff);
+        dst.w = dst.h;
+    }
+    else if (value < 400) {
+        SDL_SetRenderDrawColor(m_renderer, 0x00, 0xff, 0x00, 0xff);
+        dst.w = value;
+    }
+    else if (value < 4000) {
+        SDL_SetRenderDrawColor(m_renderer, 0xff, 0xff, 0x00, 0xff);
+        dst.w = value / 10;
+    }
+    else if (value < 400000) {
+        SDL_SetRenderDrawColor(m_renderer, 0xff, 0xaa, 0x00, 0xff);
+        dst.w = value / 1000;
+    }
+    else if (value < 40000000) {
+        SDL_SetRenderDrawColor(m_renderer, 0xff, 0x55, 0x00, 0xff);
+        dst.w = value / 100000;
+    }
+    else {
+        SDL_SetRenderDrawColor(m_renderer, 0xff, 0x00, 0x00, 0xff);
+        dst.w = value / 10000000;
+    }
+
+    // Draw
+    SDL_RenderFillRect(m_renderer, &dst);
+    SDL_SetRenderDrawColor(m_renderer, 0xaf, 0xaf, 0xaf, 0xff);
+    if (value == 0) {
+        SDL_RenderDrawLine(m_renderer, dst.x, dst.y, dst.x + dst.w - 1, dst.y + dst.h - 1);
+        SDL_RenderDrawLine(m_renderer, dst.x, dst.y + dst.h - 1, dst.x + dst.w - 1, dst.y);
+    } else {
+        dst.w = 400;
+    }
+    SDL_RenderDrawRect(m_renderer, &dst);
+}*/
+
+void Renderer::presentWindow() {
+    // Activate display
+    SDL_RenderPresent(m_renderer);
+}
+
+bool Renderer::loadStringTexture(std::string name) {
+    // Render text surface
+    //SDL_Surface* textSurface = TTF_RenderText_Solid(m_font, name.c_str(), {0, 255, 0, 255});
+    SDL_Surface *textSurface = TTF_RenderText_Shaded(m_font, name.c_str(), {0x00, 0xff, 0x00, 0xff},
+                                                     {0x66, 0x66, 0x66, 0xff});
+
+    if (textSurface == NULL) {
+        std::cout << "Renderer::loadStringTexture() [1] > " << TTF_GetError() << std::endl << std::endl;
+        return false;
+    }
+
+    // Create texture from surface pixels
+    SDL_Texture *texture(SDL_CreateTextureFromSurface(m_renderer, textSurface));
+    SDL_FreeSurface(textSurface);
+
+    if (texture == NULL) {
+        std::cout << "Renderer::loadStringTexture() [2] > " << SDL_GetError() << std::endl << std::endl;
+        return false;
+    }
+
+    m_stringTab[name] = texture;
+
+    // All right
+    return true;
+}
+
+SDL_Window *Renderer::getWindow() const {
+    return m_window;
+}

+ 44 - 0
sdl2/metaBallsVisualizer/Graphics/Renderer.h

@@ -0,0 +1,44 @@
+//
+// Created by jovian on 18/07/17.
+// Adapted for MetaBall
+
+#ifndef TINYSHOOTER_RENDERER_H
+#define TINYSHOOTER_RENDERER_H
+
+#include "../constantes.h"
+#include <SDL.h>
+#include <vector>
+#include <map>
+#include <SDL_ttf.h>
+
+class Renderer {
+public :
+    Renderer();
+
+    virtual ~Renderer();
+
+    bool initialize(); // Initialize SDL and load features (return false if error)
+
+    void clearWindow(); // Clear all content
+    void renderName(SDL_Rect &dst, std::string name);
+    void renderBoolMatrix(bool mat[WIN_H][WIN_W]);
+    void presentWindow(); // Refresh window
+
+    SDL_Window *getWindow() const;
+
+private:
+    bool loadStringTexture(std::string name); // Load a texture from a string
+
+protected:
+    int m_screenWidth;
+    int m_screenHeight;
+
+    SDL_Window *m_window; // SDL main window
+    SDL_Renderer *m_renderer; // SDL main renderer
+    TTF_Font *m_font; // TTF main font
+    std::vector<SDL_Texture *> m_pictureTab; // Every game texture
+    std::map<std::string, SDL_Texture *> m_stringTab; // Every game name texture
+};
+
+
+#endif //TINYSHOOTER_RENDERER_H

+ 11 - 0
sdl2/metaBallsVisualizer/constantes.h

@@ -0,0 +1,11 @@
+//
+// Created by jovian on 15/11/17.
+//
+
+#ifndef METABALLVISUALIZER_CONSTANTES_H
+#define METABALLVISUALIZER_CONSTANTES_H
+
+#define WIN_W 800
+#define WIN_H 600
+
+#endif //METABALLVISUALIZER_CONSTANTES_H

二進制
sdl2/metaBallsVisualizer/droid.ttf


+ 28 - 0
sdl2/metaBallsVisualizer/main.cpp

@@ -0,0 +1,28 @@
+// Includes
+#include <iostream>
+#include "GameCore.h"
+
+using namespace std;
+
+int main() {
+    // Start
+    cout << "MetaBalls visualizer starts." << endl;
+
+    // Random start
+    srand((unsigned int) time(0));
+
+    // Initialisation
+    GameCore core;
+
+    if (!core.initialize()){
+        cout << "MetaBallVisualizer has encountered a problem." << endl;
+        cout << "Ask Jovian to debug his program ..." << endl;
+        return 1;
+    }
+
+    // QuickGame
+    core.start();
+
+    // End
+    return 0;
+}