Skip to content

Commit

Permalink
add: support for sdl2, basis of media
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanCui4080 committed Feb 21, 2024
1 parent bb960e3 commit eef1739
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 20 deletions.
10 changes: 8 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED true)
set(CMAKE_CXX_STANDARD 23)
find_package(PkgConfig REQUIRED)
find_package(Boost REQUIRED)
find_package(SDL2 REQUIRED)
find_package(SDL2_Image REQUIRED)
find_package(SDL2_Mixer REQUIRED)
pkg_check_modules(ZIP libzip REQUIRED)

file(GLOB PROJ_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
Expand All @@ -18,8 +21,11 @@ add_compile_options(-fsanitize=leak -fsanitize=address -fsanitize=undefined)
add_link_options(-fsanitize=leak -fsanitize=address -fsanitize=undefined)

add_library(scratch3 ${PROJ_SRC})
target_include_directories(scratch3 PRIVATE ${BOOST_INCLUDE_DIRS} ${ZIP_INCLUDE_DIRS})
target_link_libraries(scratch3 ${BOOST_LIBRARIES} ${ZIP_LIBRARIES})
target_include_directories(scratch3 PRIVATE ${BOOST_INCLUDE_DIRS} ${ZIP_INCLUDE_DIRS}
${SDL2_INCLUDE_DIRS} ${SDL2_Image_INCLUDE_DIRS} ${SDL2_Mixer_INCLUDE_DIRS})

target_link_libraries(scratch3 ${BOOST_LIBRARIES} ${ZIP_LIBRARIES}
${SDL2_LIBRARIES} ${SDL2_Image_LIBRARIES} ${SDL2_Mixer_LIBRARIES})

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
Expand Down
4 changes: 4 additions & 0 deletions src/exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ const char* file_format_error::what() const noexcept
{
return std::format("file_format_error: {} \n at: {}",s_what,ss_va.str()).c_str();
}
const char* sdl_error::what() const noexcept
{
return SDL_GetError();
}
18 changes: 14 additions & 4 deletions src/exception.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <zip.h>
#include <boost/json.hpp>
#include <sstream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
namespace libsc3
{
class libzip_runtime_error : public std::exception
Expand All @@ -13,19 +15,27 @@ namespace libsc3

public:
virtual const char* what() const noexcept override final;

public:
libzip_runtime_error(int zip_errorno);
libzip_runtime_error(zip_t* p);
~libzip_runtime_error();
};
class file_format_error : public std::exception
{
private:
std::string s_what;
private:
std::string s_what;
std::stringstream ss_va;
public:

public:
virtual const char* what() const noexcept override final;
public:

public:
file_format_error(const std::string& what, boost::json::value& va);
};
class sdl_error : public std::exception
{
public:
virtual const char* what() const noexcept override final;
};
} // namespace libsc3
11 changes: 11 additions & 0 deletions src/player.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "player.hpp"
#include "exception.hpp"
using namespace libsc3;
player::player(SDL_Window* window)
{
this->player_renderer = SDL_CreateRenderer(window, -1, renderer_flag);
if(this->player_renderer == nullptr)
{
throw sdl_error();
}
}
15 changes: 15 additions & 0 deletions src/player.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once
#include <SDL2/SDL.h>
#include <memory>
namespace libsc3
{
class player
{
public:
static constexpr auto renderer_flag = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
private:
SDL_Renderer* player_renderer;
public:
player(SDL_Window* window);
};
} // namespace libsc3
108 changes: 99 additions & 9 deletions src/project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ project::project(const std::filesystem::path& path)
std::string_view target_name_view = i.as_object()["name"].as_string();
if (i.as_object()["isStage"].as_bool())
{
auto stage_object = stage(i);
auto stage_object = stage(i, this->element_list);
auto result =
this->target_list.emplace(std::string(target_name_view), std::move(stage_object));

Expand All @@ -66,34 +66,124 @@ project::project(const std::filesystem::path& path)
else
{
auto&& stage_ref = dynamic_cast<stage&>((*this->stage_target).second);
auto target_object = target(stage_ref, i);
auto target_object = target(stage_ref, i, this->element_list);
this->target_list.emplace(std::string(target_name_view), std::move(target_object));
}
}
}
}
project::~project()
{
zip_close(this->compressed_bundle);
for (auto&& i : this->element_list)
{
zip_fclose(i.second);
}
zip_close(this->compressed_bundle);
}
target::target(boost::json::value& json_value)
static inline target::variable_value_type variable_value_helper(boost::json::value& va)
{
if (va.is_int64())
{
return target::variable_value_type(va.as_int64());
}
else if (va.is_double())
{
return target::variable_value_type(va.as_double());
}
else if (va.is_string())
{
return target::variable_value_type(std::string(va.as_string()));
}
else
{
throw file_format_error("a variable is neither a number nor a string", va);
}
}

target::target(stage& stage, boost::json::value& json_value,
std::unordered_map<std::string, element_file_type>& elem_list)
{
this->name = json_value.as_object()["name"].as_string();
for (auto&& i : json_value.as_object()["variables"].as_object())
{
std::string_view key_view = i.key();
std::string_view variable_name_view = i.value().as_array()[0].as_string();
if (i.value().as_array()[1].is_array())
{
auto&& this_array = i.value().as_array()[1].as_array();
std::vector<variable_value_type> value_vector;
std::for_each(this_array.begin(), this_array.end(),
[&](decltype(*this_array.begin()) it) {
value_vector.emplace_back(variable_value_helper(it));
});
auto value_pair =
std::make_pair(std::string(variable_name_view), std::move(value_vector));
this->variable_list.insert_or_assign(std::string(key_view), std::move(value_pair));
}
else
{
std::vector<variable_value_type> value_vector;
value_vector.push_back(variable_value_helper(i.value().as_array()[1]));

auto value_pair =
std::make_pair(std::string(variable_name_view), i.value().as_array()[1].as_int64());
this->variable_list.insert_or_assign(std::string(key_view), std::move(value_pair));
auto value_pair =
std::make_pair(std::string(variable_name_view), std::move(value_vector));
this->variable_list.insert_or_assign(std::string(key_view), std::move(value_pair));
}
}
for (auto&& i : json_value.as_object()["costumes"].as_array())
{
auto costume_name = std::string(i.as_object()["name"].as_string());
static constexpr auto buffer_block_step = 4096;
auto buffer_size = buffer_block_step;
auto costume_buffer = std::calloc(buffer_size, 1);
while (!zip_fread(elem_list[std::string(i.as_object()["md5ext"].as_string())],
costume_buffer, buffer_size))
{
buffer_size += 4096;
costume_buffer = std::realloc(costume_buffer, buffer_size);
}
auto costume_rw = SDL_RWFromMem(costume_buffer, buffer_size);
if (costume_rw == nullptr)
{
throw sdl_error();
}
auto data_fmt_str = i.as_object()["dataFormat"].as_string().c_str();
auto costume_surface = IMG_LoadTyped_RW(costume_rw, 1, data_fmt_str);
if (costume_surface == nullptr)
{
throw sdl_error();
}
costume_list.insert_or_assign(costume_name, costume_surface);
std::free(costume_buffer);
}
for (auto&& i : json_value.as_object()["sounds"].as_array())
{
auto sound_name = std::string(i.as_object()["name"].as_string());
static constexpr auto buffer_block_step = 4096;
auto buffer_size = buffer_block_step;
auto sound_buffer = std::calloc(buffer_size, 1);
while (!zip_fread(elem_list[std::string(i.as_object()["md5ext"].as_string())], sound_buffer,
buffer_size))
{
buffer_size += 4096;
sound_buffer = std::realloc(sound_buffer, buffer_size);
}
auto sound_rw = SDL_RWFromMem(sound_buffer, buffer_size);
if (sound_rw == nullptr)
{
throw sdl_error();
}
auto sound_target = Mix_LoadMUS_RW(sound_rw, 1);
if (sound_target == nullptr)
{
throw sdl_error();
}
sound_list.insert_or_assign(sound_name, sound_target);
std::free(sound_buffer);
}
}
stage::stage(boost::json::value& json_value)
: target(json_value)
stage::stage(boost::json::value& json_value,
std::unordered_map<std::string, element_file_type>& elem_list)
: target(*this, json_value, elem_list)
{
}
20 changes: 15 additions & 5 deletions src/project.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <unordered_map>
#include <variant>
#include <boost/json.hpp>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL.h>
namespace libsc3
{
class stage;
Expand All @@ -16,26 +19,33 @@ namespace libsc3

public:
typedef std::variant<std::string, std::int64_t, double> variable_value_type;
typedef SDL_Surface* renderer_surface_type;
typedef Mix_Music* mixer_sound_type;
typedef zip_file_t* element_file_type;

private:
std::string_view name;
std::unordered_map<std::string, std::pair<std::string, variable_value_type>> variable_list;
std::string_view name;
std::unordered_map<std::string, std::pair<std::string, std::vector<variable_value_type>>>
variable_list;
std::unordered_map<std::string, renderer_surface_type> costume_list;
std::unordered_map<std::string, mixer_sound_type> sound_list;

private:
target(boost::json::value& json_value);
virtual constexpr auto get_variable_list() noexcept -> decltype(variable_list)&
{
return variable_list;
}

public:
target(stage& stage, boost::json::value& json_value);
target(stage& stage, boost::json::value& json_value,
std::unordered_map<std::string, element_file_type>& elem_list);
};

class stage : public target
{
public:
stage(boost::json::value& json_value);
stage(boost::json::value& json_value,
std::unordered_map<std::string, element_file_type>& elem_list);
virtual constexpr auto get_variable_list() noexcept -> decltype(variable_list)& override
{
return variable_list;
Expand Down

0 comments on commit eef1739

Please sign in to comment.