Skip to content

Commit

Permalink
Merge pull request #75 from AlwinEsch/Nexus-change
Browse files Browse the repository at this point in the history
[Nexus] feature to use JSON file about usable presets and allow to change by user
  • Loading branch information
AlwinEsch authored Sep 13, 2021
2 parents 613055d + 0f0deb4 commit 53d1b61
Showing 85 changed files with 7,311 additions and 100 deletions.
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR})

find_package(Kodi REQUIRED)
find_package(glm REQUIRED)
find_package(JsonCpp REQUIRED)

add_subdirectory(lib/kissfft)

@@ -24,16 +25,21 @@ include_directories(${GLM_INCLUDE_DIR}
${KODI_INCLUDE_DIR}/.. # Hack way with "/..", need bigger Kodi cmake rework to match right include ways
${PROJECT_SOURCE_DIR}/lib)

list(APPEND DEPLIBS ${JSONCPP_LIBRARIES})
list(APPEND INCLUDES ${JSONCPP_INCLUDE_DIRS})

if(CORE_SYSTEM_NAME STREQUAL osx OR
CORE_SYSTEM_NAME STREQUAL ios OR
CORE_SYSTEM_NAME STREQUAL darwin_embedded)
list(APPEND DEPLIBS "-framework CoreVideo")
endif()

set(SHADERTOY_SOURCES src/lodepng.cpp
set(SHADERTOY_SOURCES src/PresetsLoader.cpp
src/lodepng.cpp
src/main.cpp)

set(SHADERTOY_HEADERS src/lodepng.h
set(SHADERTOY_HEADERS src/PresetsLoader.h
src/lodepng.h
src/main.h)

list(APPEND DEPLIBS kissfft)
15 changes: 15 additions & 0 deletions FindJsonCpp.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_JSONCPP jsoncpp)
endif()

find_path(JSONCPP_INCLUDE_DIRS json/json.h
PATHS ${PC_JSONCPP_INCLUDEDIR}
PATH_SUFFIXES jsoncpp)
find_library(JSONCPP_LIBRARIES jsoncpp
PATHS ${PC_JSONCPP_LIBDIR})

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(JsonCpp REQUIRED_VARS JSONCPP_LIBRARIES JSONCPP_INCLUDE_DIRS)

mark_as_advanced(JSONCPP_INCLUDE_DIRS JSONCPP_LIBRARIES)
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -15,6 +15,8 @@ When building the addon you have to use the correct branch depending on which ve
If you want to build the addon to be compatible with the latest kodi `master` commit, you need to checkout the branch with the current kodi codename.
Also make sure you follow this README from the branch in question.

If you want to use your own shaders, see [instructions for creating your own preset list](visualization.shadertoy/resources/presets.json.md).

### Linux

The following instructions assume you will have built Kodi already in the `kodi-build` directory
3 changes: 2 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
@@ -2,7 +2,8 @@ Source: kodi-visualization-shadertoy
Priority: extra
Maintainer: Nobody <nobody@kodi.tv>
Build-Depends: debhelper (>= 9.0.0), cmake, kodi-addon-dev, libglm-dev,
libgles2-mesa-dev [arm64 armhf], libgl1-mesa-dev [i386 amd64]
libgles2-mesa-dev [arm64 armhf], libgl1-mesa-dev [i386 amd64],
libjsoncpp-dev
Standards-Version: 4.1.2
Section: libs
Homepage: https://kodi.tv
1 change: 1 addition & 0 deletions depends/common/jsoncpp/flags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-DJSONCPP_WITH_TESTS=0 -DJSONCPP_WITH_POST_BUILD_UNITTEST=0 -DBUILD_SHARED_LIBS=0 -DBUILD_OBJECT_LIBS=0
1 change: 1 addition & 0 deletions depends/common/jsoncpp/jsoncpp.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e34a628a8142643b976c7233ef381457efad79468c67cb1ae0b83a33d7493999
1 change: 1 addition & 0 deletions depends/common/jsoncpp/jsoncpp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jsoncpp https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.9.4.tar.gz
179 changes: 179 additions & 0 deletions src/PresetsLoader.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* Copyright (C) 2005-2021 Team Kodi (https://kodi.tv)
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSE.md for more information.
*/

#include "PresetsLoader.h"

#include <json/json.h>
#include <kodi/Filesystem.h>
#include <kodi/General.h>
#include <kodi/tools/StringUtils.h>

bool CPresetLoader::Load(const std::string& path)
{
bool ret = false;
char* ptr = nullptr;

try
{
kodi::vfs::CFile file;
if (!file.OpenFile(path))
{
throw kodi::tools::StringUtils::Format("Failed to open shader list file %s", path.c_str());
}

ssize_t length = file.GetLength();
if (length <= 0)
{
throw kodi::tools::StringUtils::Format("Shader list file %s seems empty and not usable",
path.c_str());
}

ptr = new char[length + 1]{0};
ssize_t pos = 0;
do
{
ssize_t ret = file.Read(ptr, length);
if (ret < 0)
{
throw kodi::tools::StringUtils::Format("Failed to read shader list file %s", path.c_str());
}
pos += ret;
} while (pos < length);

try
{
JSONCPP_STRING err;
Json::Value root;
Json::CharReaderBuilder builder;
const std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
if (!reader->parse(ptr, ptr + length, &root, &err))
{
throw kodi::tools::StringUtils::Format(
"Failed to parse json within shader list file %s (ERROR: %s)", path.c_str(),
err.c_str());
}

for (unsigned int index = 0; index < root["presets"].size(); index++)
{
const auto& entry = root["presets"][index];
Preset preset;

// Check the optional JSON value at the end of the preset, which sets
// possible limits, e.g. supporting only GL ("gl_only")
if (entry.size() > 6 && entry[6].isString())
{
#if !defined(HAS_GL)
if (kodi::tools::StringUtils::CompareNoCase(entry[6].asString(), "gl_only") == 0)
continue;
#endif
}

if (entry[0].isString())
preset.name = entry[0].asString();
else
preset.name = kodi::GetLocalizedString(entry[0].asInt(), "Unknown preset name " +
std::to_string(index + 1));

// Check shader file included within addon or outside and set by user
const std::string usedDirName = kodi::vfs::GetDirectoryName(entry[1].asString());
if (usedDirName.rfind("./", 0) == 0)
preset.file =
kodi::vfs::GetDirectoryName(path) + kodi::vfs::GetFileName(entry[1].asString());
else if (usedDirName.rfind("../", 0) == 0)
preset.file = kodi::vfs::GetDirectoryName(path) + entry[1].asString();
else if (!usedDirName.empty())
preset.file = entry[1].asString();
else
preset.file = kodi::GetAddonPath("resources/shaders/" + entry[1].asString());

if (!kodi::vfs::FileExists(preset.file))
throw kodi::tools::StringUtils::Format("On %s defined GLSL shader file '%s' not found",
path.c_str(), preset.file.c_str());

for (unsigned int i = 0; i < 4; ++i)
{
// Check shader file included within addon or outside and set by user
const std::string usedDirName = kodi::vfs::GetDirectoryName(entry[i + 2].asString());
if (kodi::tools::StringUtils::CompareNoCase(entry[i + 2].asString(), "audio") == 0)
preset.channel[i] = "audio";
else if (usedDirName.rfind("./", 0) == 0)
preset.channel[i] =
kodi::vfs::GetDirectoryName(path) + kodi::vfs::GetFileName(entry[i + 2].asString());
else if (usedDirName.rfind("../", 0) == 0)
preset.channel[i] = kodi::vfs::GetDirectoryName(path) + entry[i + 2].asString();
else if (!usedDirName.empty())
preset.channel[i] = entry[i + 2].asString();
else if (!entry[i + 2].asString().empty())
preset.channel[i] = kodi::GetAddonPath("resources/" + entry[i + 2].asString());

if (!preset.channel[i].empty() && preset.channel[i] != "audio")
{
if (!kodi::vfs::FileExists(preset.channel[i]))
throw kodi::tools::StringUtils::Format("On %s defined texture image '%s' not found",
path.c_str(), preset.channel[i].c_str());
}
}

m_presets.emplace_back(preset);
}
}
catch (Json::LogicError err)
{
throw kodi::tools::StringUtils::Format("Json throwed an exception by parse of %s with '%s'",
path.c_str(), err.what());
}
catch (std::string err)
{
throw std::move(err);
}
catch (...)
{
throw kodi::tools::StringUtils::Format("Exception by parse of %s", path.c_str());
}

ret = true;
}
catch (std::string err)
{
kodi::Log(ADDON_LOG_ERROR, "%s: %s", __func__, err.c_str());
}
catch (...)
{
kodi::Log(ADDON_LOG_ERROR, "%s: Unknown exception by load of %s", __func__, path.c_str());
}

if (ptr)
delete[] ptr;

// Inform user that maybe their own preset list is wrong
if (!ret)
kodi::QueueNotification(QUEUE_OWN_STYLE, kodi::GetLocalizedString(30030),
kodi::GetLocalizedString(30031), "", 5000, true, 20000);

return ret;
}

bool CPresetLoader::GetAvailablePresets(std::vector<std::string>& presets)
{
for (auto preset : m_presets)
presets.push_back(preset.name);
return true;
}

int CPresetLoader::GetPresetsAmount()
{
return static_cast<int>(m_presets.size());
}

Preset CPresetLoader::GetPreset(int number)
{
if (number >= 0 && number < m_presets.size())
return m_presets[number];

static Preset empty;
return empty;
}
34 changes: 34 additions & 0 deletions src/PresetsLoader.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2005-2021 Team Kodi (https://kodi.tv)
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSE.md for more information.
*/

#pragma once

#include <string>
#include <vector>

struct Preset
{
std::string name;
std::string file;
std::string channel[4];
};

class CPresetLoader
{
public:
CPresetLoader() = default;
~CPresetLoader() = default;

bool Load(const std::string& path);

bool GetAvailablePresets(std::vector<std::string>& presets);
int GetPresetsAmount();
Preset GetPreset(int number);

private:
std::vector<Preset> m_presets;
};
Loading

0 comments on commit 53d1b61

Please sign in to comment.