Merge branch 'dev' into debugging-client
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "graphics/core/Atlas.hpp"
|
||||
#include "util/Buffer.hpp"
|
||||
#include "../lua_custom_types.hpp"
|
||||
#include "../usertypes/lua_type_canvas.hpp"
|
||||
|
||||
using namespace scripting;
|
||||
|
||||
|
||||
@@ -68,6 +68,26 @@ inline audio::speakerid_t play_stream(
|
||||
if (channel == -1) {
|
||||
return 0;
|
||||
}
|
||||
if (!scripting::engine->isHeadless()) {
|
||||
auto assets = scripting::engine->getAssets();
|
||||
|
||||
auto stream = assets->getShared<audio::PCMStream>(filename);
|
||||
if (stream) {
|
||||
return audio::play(
|
||||
audio::open_stream(std::move(stream), true),
|
||||
glm::vec3(
|
||||
static_cast<float>(x),
|
||||
static_cast<float>(y),
|
||||
static_cast<float>(z)
|
||||
),
|
||||
relative,
|
||||
volume,
|
||||
pitch,
|
||||
loop,
|
||||
channel
|
||||
);
|
||||
}
|
||||
}
|
||||
io::path file;
|
||||
if (std::strchr(filename, ':')) {
|
||||
file = std::string(filename);
|
||||
@@ -360,16 +380,80 @@ static int l_audio_get_velocity(lua::State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// @brief audio.count_speakers() -> integer
|
||||
/// @brief audio.count_speakers() -> integer
|
||||
static int l_audio_count_speakers(lua::State* L) {
|
||||
return lua::pushinteger(L, audio::count_speakers());
|
||||
}
|
||||
|
||||
// @brief audio.count_streams() -> integer
|
||||
/// @brief audio.count_streams() -> integer
|
||||
static int l_audio_count_streams(lua::State* L) {
|
||||
return lua::pushinteger(L, audio::count_streams());
|
||||
}
|
||||
|
||||
/// @brief audio.input.fetch(size) -> Bytearray
|
||||
static int l_audio_fetch_input(lua::State* L) {
|
||||
auto device = audio::get_input_device();
|
||||
if (device == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
size_t size = lua::touinteger(L, 1);
|
||||
const size_t MAX_BUFFER_SIZE = audio::MAX_INPUT_SAMPLES * 4;
|
||||
if (size == 0) {
|
||||
size = MAX_BUFFER_SIZE;
|
||||
}
|
||||
size = std::min<size_t>(size, MAX_BUFFER_SIZE);
|
||||
ubyte buffer[MAX_BUFFER_SIZE];
|
||||
size = device->read(reinterpret_cast<char*>(buffer), size);
|
||||
|
||||
std::vector<ubyte> bytes(buffer, buffer + size);
|
||||
return lua::create_bytearray(L, std::move(bytes));
|
||||
}
|
||||
|
||||
static int l_audio_get_input_devices_names(lua::State* L) {
|
||||
auto device_names = audio::get_input_devices_names();
|
||||
lua::createtable(L, device_names.size(), 0);
|
||||
int index = 1;
|
||||
for (const auto& name : device_names) {
|
||||
lua::pushstring(L, name.c_str());
|
||||
lua::rawseti(L, index++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_audio_get_output_devices_names(lua::State* L) {
|
||||
auto device_names = audio::get_output_devices_names();
|
||||
lua::createtable(L, device_names.size(), 0);
|
||||
int index = 1;
|
||||
for (const auto& name : device_names) {
|
||||
lua::pushstring(L, name.c_str());
|
||||
lua::rawseti(L, index++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_audio_set_input_device(lua::State* L) {
|
||||
auto device_name = lua::tostring(L, 1);
|
||||
audio::set_input_device(device_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_audio_get_input_info(lua::State* L) {
|
||||
auto device = audio::get_input_device();
|
||||
if (device == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
lua::createtable(L, 0, 4);
|
||||
lua::pushlstring(L, device->getDeviceSpecifier());
|
||||
lua::setfield(L, "device_specifier");
|
||||
lua::pushinteger(L, device->getChannels());
|
||||
lua::setfield(L, "channels");
|
||||
lua::pushinteger(L, device->getSampleRate());
|
||||
lua::setfield(L, "sample_rate");
|
||||
lua::pushinteger(L, device->getBitsPerSample());
|
||||
lua::setfield(L, "bits_per_sample");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const luaL_Reg audiolib[] = {
|
||||
{"play_sound", lua::wrap<l_audio_play_sound>},
|
||||
{"play_sound_2d", lua::wrap<l_audio_play_sound_2d>},
|
||||
@@ -395,5 +479,10 @@ const luaL_Reg audiolib[] = {
|
||||
{"get_velocity", lua::wrap<l_audio_get_velocity>},
|
||||
{"count_speakers", lua::wrap<l_audio_count_speakers>},
|
||||
{"count_streams", lua::wrap<l_audio_count_streams>},
|
||||
{"__fetch_input", lua::wrap<l_audio_fetch_input>},
|
||||
{"get_input_devices_names", lua::wrap<l_audio_get_input_devices_names>},
|
||||
{"get_output_devices_names", lua::wrap<l_audio_get_output_devices_names>},
|
||||
{"set_input_device", lua::wrap<l_audio_set_input_device>},
|
||||
{"get_input_info", lua::wrap<l_audio_get_input_info>},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "coders/binary_json.hpp"
|
||||
#include "api_lua.hpp"
|
||||
#include "util/Buffer.hpp"
|
||||
#include "../lua_custom_types.hpp"
|
||||
|
||||
static int l_tobytes(lua::State* L) {
|
||||
auto value = lua::tovalue(L, 1);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "content/ContentControl.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
#include "engine/EnginePaths.hpp"
|
||||
#include "../lua_custom_types.hpp"
|
||||
#include "../usertypes/lua_type_voxelfragment.hpp"
|
||||
|
||||
using namespace scripting;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "items/Inventories.hpp"
|
||||
#include "util/stringutil.hpp"
|
||||
#include "world/Level.hpp"
|
||||
#include "../usertypes/lua_type_canvas.hpp"
|
||||
|
||||
using namespace gui;
|
||||
using namespace scripting;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <vector>
|
||||
#include <cwctype>
|
||||
|
||||
#include "../lua_custom_types.hpp"
|
||||
#include "util/stringutil.hpp"
|
||||
|
||||
static int l_tobytes(lua::State* L) {
|
||||
|
||||
@@ -48,4 +48,9 @@ namespace lua {
|
||||
|
||||
void log_error(const std::string& text);
|
||||
|
||||
class Userdata {
|
||||
public:
|
||||
virtual ~Userdata() {};
|
||||
virtual const std::string& getTypeName() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <random>
|
||||
|
||||
#include "lua_commons.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "maths/UVRegion.hpp"
|
||||
|
||||
struct fnl_state;
|
||||
class Heightmap;
|
||||
class VoxelFragment;
|
||||
class Texture;
|
||||
class ImageData;
|
||||
|
||||
namespace lua {
|
||||
class Userdata {
|
||||
public:
|
||||
virtual ~Userdata() {};
|
||||
virtual const std::string& getTypeName() const = 0;
|
||||
};
|
||||
|
||||
class LuaHeightmap : public Userdata {
|
||||
std::shared_ptr<Heightmap> map;
|
||||
std::unique_ptr<fnl_state> noise;
|
||||
public:
|
||||
LuaHeightmap(const std::shared_ptr<Heightmap>& map);
|
||||
LuaHeightmap(uint width, uint height);
|
||||
|
||||
virtual ~LuaHeightmap();
|
||||
|
||||
uint getWidth() const;
|
||||
|
||||
uint getHeight() const;
|
||||
|
||||
float* getValues();
|
||||
|
||||
const float* getValues() const;
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Heightmap>& getHeightmap() const {
|
||||
return map;
|
||||
}
|
||||
|
||||
fnl_state* getNoise() {
|
||||
return noise.get();
|
||||
}
|
||||
|
||||
void setSeed(int64_t seed);
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "Heightmap";
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaHeightmap>());
|
||||
|
||||
class LuaVoxelFragment : public Userdata {
|
||||
std::array<std::shared_ptr<VoxelFragment>, 4> fragmentVariants;
|
||||
public:
|
||||
LuaVoxelFragment(
|
||||
std::array<std::shared_ptr<VoxelFragment>, 4> fragmentVariants
|
||||
);
|
||||
|
||||
virtual ~LuaVoxelFragment();
|
||||
|
||||
std::shared_ptr<VoxelFragment> getFragment(size_t rotation) const {
|
||||
return fragmentVariants.at(rotation & 0b11);
|
||||
}
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "VoxelFragment";
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaVoxelFragment>());
|
||||
|
||||
class LuaCanvas : public Userdata {
|
||||
public:
|
||||
explicit LuaCanvas(
|
||||
std::shared_ptr<Texture> texture,
|
||||
std::shared_ptr<ImageData> data,
|
||||
UVRegion region = UVRegion(0, 0, 1, 1)
|
||||
);
|
||||
~LuaCanvas() override = default;
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto& getTexture() const {
|
||||
return *texture;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto& getData() const {
|
||||
return *data;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool hasTexture() const {
|
||||
return texture != nullptr;
|
||||
}
|
||||
|
||||
auto shareTexture() const {
|
||||
return texture;
|
||||
}
|
||||
|
||||
void update(int extrusion = ATLAS_EXTRUSION);
|
||||
|
||||
void createTexture();
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "Canvas";
|
||||
private:
|
||||
std::shared_ptr<Texture> texture; // nullable
|
||||
std::shared_ptr<ImageData> data;
|
||||
UVRegion region;
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaCanvas>());
|
||||
|
||||
class LuaRandom : public Userdata {
|
||||
public:
|
||||
std::mt19937 rng;
|
||||
|
||||
explicit LuaRandom(uint64_t seed) : rng(seed) {}
|
||||
virtual ~LuaRandom() override = default;
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "__vc_Random";
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaRandom>());
|
||||
}
|
||||
@@ -8,7 +8,11 @@
|
||||
#include "debug/Logger.hpp"
|
||||
#include "util/stringutil.hpp"
|
||||
#include "libs/api_lua.hpp"
|
||||
#include "lua_custom_types.hpp"
|
||||
#include "usertypes/lua_type_heightmap.hpp"
|
||||
#include "usertypes/lua_type_voxelfragment.hpp"
|
||||
#include "usertypes/lua_type_canvas.hpp"
|
||||
#include "usertypes/lua_type_random.hpp"
|
||||
#include "usertypes/lua_type_pcmstream.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
|
||||
static debug::Logger logger("lua-state");
|
||||
@@ -181,5 +185,12 @@ State* lua::create_state(const EnginePaths& paths, StateType stateType) {
|
||||
}
|
||||
pop(L);
|
||||
}
|
||||
newusertype<LuaPCMStream>(L);
|
||||
if (getglobal(L, "audio")) {
|
||||
if (getglobal(L, "__vc_PCMStream")) {
|
||||
setfield(L, "PCMStream");
|
||||
}
|
||||
pop(L);
|
||||
}
|
||||
return L;
|
||||
}
|
||||
|
||||
@@ -155,18 +155,18 @@ static int l_error_handler(lua_State* L) {
|
||||
}
|
||||
|
||||
int lua::call(State* L, int argc, int nresults) {
|
||||
int handler_pos = gettop(L) - argc;
|
||||
int handlerPos = gettop(L) - argc;
|
||||
pushcfunction(L, l_error_handler);
|
||||
insert(L, handler_pos);
|
||||
insert(L, handlerPos);
|
||||
int top = gettop(L);
|
||||
if (lua_pcall(L, argc, nresults, handler_pos)) {
|
||||
if (lua_pcall(L, argc, nresults, handlerPos)) {
|
||||
std::string log = tostring(L, -1);
|
||||
pop(L);
|
||||
remove(L, handler_pos);
|
||||
remove(L, handlerPos);
|
||||
throw luaerror(log);
|
||||
}
|
||||
int added = gettop(L) - (top - argc - 1);
|
||||
remove(L, handler_pos);
|
||||
remove(L, handlerPos);
|
||||
return added;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "data/dv.hpp"
|
||||
#include "lua_custom_types.hpp"
|
||||
#include "lua_wrapper.hpp"
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include <unordered_map>
|
||||
#include "lua_type_canvas.hpp"
|
||||
|
||||
#include "graphics/core/ImageData.hpp"
|
||||
#include "graphics/core/Texture.hpp"
|
||||
#include "logic/scripting/lua/lua_custom_types.hpp"
|
||||
#include "logic/scripting/lua/lua_util.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
#include "assets/Assets.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace lua;
|
||||
|
||||
LuaCanvas::LuaCanvas(
|
||||
@@ -46,7 +47,9 @@ void LuaCanvas::update(int extrusion) {
|
||||
h + extrusion * 2
|
||||
);
|
||||
extruded->blit(*data, extrusion, extrusion);
|
||||
extruded->extrude(0, 0, w + extrusion * 2, h + extrusion * 2);
|
||||
for (uint j = 0; j < extrusion; j++) {
|
||||
extruded->extrude(extrusion - j, extrusion - j, w + j*2, h + j*2);
|
||||
}
|
||||
texture->reloadPartial(
|
||||
*extruded,
|
||||
x - extrusion,
|
||||
@@ -65,6 +68,10 @@ void LuaCanvas::createTexture() {
|
||||
texture->setMipMapping(false, true);
|
||||
}
|
||||
|
||||
void LuaCanvas::unbindTexture() {
|
||||
texture.reset();
|
||||
}
|
||||
|
||||
union RGBA {
|
||||
struct {
|
||||
uint8_t r, g, b, a;
|
||||
@@ -98,7 +105,13 @@ static int l_at(State* L) {
|
||||
if (auto pixel = get_at(L, x, y)) {
|
||||
return pushinteger(L, pixel->rgba);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_unbind_texture(State* L) {
|
||||
if (auto canvas = touserdata<LuaCanvas>(L, 1)) {
|
||||
canvas->unbindTexture();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -229,6 +242,48 @@ static int l_create_texture(State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_mul(State* L) {
|
||||
auto canvas = touserdata<LuaCanvas>(L, 1);
|
||||
if (canvas == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
if (lua::isnumber(L, 2)) {
|
||||
RGBA rgba = get_rgba(L, 2);
|
||||
canvas->getData().mulColor(glm::ivec4 {rgba.r, rgba.g, rgba.b, rgba.a});
|
||||
} else if (auto other = touserdata<LuaCanvas>(L, 2)) {
|
||||
canvas->getData().mulColor(other->getData());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_add(State* L) {
|
||||
auto canvas = touserdata<LuaCanvas>(L, 1);
|
||||
if (canvas == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
if (lua::istable(L, 2)) {
|
||||
RGBA rgba = get_rgba(L, 2);
|
||||
canvas->getData().addColor(glm::ivec4 {rgba.r, rgba.g, rgba.b, rgba.a}, 1);
|
||||
} else if (auto other = touserdata<LuaCanvas>(L, 2)) {
|
||||
canvas->getData().addColor(other->getData(), 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_sub(State* L) {
|
||||
auto canvas = touserdata<LuaCanvas>(L, 1);
|
||||
if (canvas == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
if (lua::istable(L, 2)) {
|
||||
RGBA rgba = get_rgba(L, 2);
|
||||
canvas->getData().addColor(glm::ivec4 {rgba.r, rgba.g, rgba.b, rgba.a}, -1);
|
||||
} else if (auto other = touserdata<LuaCanvas>(L, 2)) {
|
||||
canvas->getData().addColor(other->getData(), -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, lua_CFunction> methods {
|
||||
{"at", lua::wrap<l_at>},
|
||||
{"set", lua::wrap<l_set>},
|
||||
@@ -237,6 +292,10 @@ static std::unordered_map<std::string, lua_CFunction> methods {
|
||||
{"clear", lua::wrap<l_clear>},
|
||||
{"update", lua::wrap<l_update>},
|
||||
{"create_texture", lua::wrap<l_create_texture>},
|
||||
{"unbind_texture", lua::wrap<l_unbind_texture>},
|
||||
{"mul", lua::wrap<l_mul>},
|
||||
{"add", lua::wrap<l_add>},
|
||||
{"sub", lua::wrap<l_sub>},
|
||||
{"_set_data", lua::wrap<l_set_data>},
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "../lua_commons.hpp"
|
||||
#include "maths/UVRegion.hpp"
|
||||
#include "constants.hpp"
|
||||
|
||||
class Texture;
|
||||
class ImageData;
|
||||
|
||||
namespace lua {
|
||||
class LuaCanvas : public Userdata {
|
||||
public:
|
||||
explicit LuaCanvas(
|
||||
std::shared_ptr<Texture> texture,
|
||||
std::shared_ptr<ImageData> data,
|
||||
UVRegion region = UVRegion(0, 0, 1, 1)
|
||||
);
|
||||
~LuaCanvas() override = default;
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto& getTexture() const {
|
||||
return *texture;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto& getData() const {
|
||||
return *data;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool hasTexture() const {
|
||||
return texture != nullptr;
|
||||
}
|
||||
|
||||
auto shareTexture() const {
|
||||
return texture;
|
||||
}
|
||||
|
||||
void update(int extrusion = ATLAS_EXTRUSION);
|
||||
|
||||
void createTexture();
|
||||
void unbindTexture();
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "Canvas";
|
||||
private:
|
||||
std::shared_ptr<Texture> texture; // nullable
|
||||
std::shared_ptr<ImageData> data;
|
||||
UVRegion region;
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaCanvas>());
|
||||
}
|
||||
@@ -1,9 +1,4 @@
|
||||
#include "../lua_custom_types.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <filesystem>
|
||||
#include "lua_type_heightmap.hpp"
|
||||
|
||||
#include "util/functional_util.hpp"
|
||||
#define FNL_IMPL
|
||||
@@ -15,6 +10,12 @@
|
||||
#include "engine/Engine.hpp"
|
||||
#include "engine/EnginePaths.hpp"
|
||||
#include "../lua_util.hpp"
|
||||
#include "lua_type_heightmap.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <filesystem>
|
||||
|
||||
using namespace lua;
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include "../lua_commons.hpp"
|
||||
|
||||
struct fnl_state;
|
||||
class Heightmap;
|
||||
|
||||
namespace lua {
|
||||
class LuaHeightmap : public Userdata {
|
||||
std::shared_ptr<Heightmap> map;
|
||||
std::unique_ptr<fnl_state> noise;
|
||||
public:
|
||||
LuaHeightmap(const std::shared_ptr<Heightmap>& map);
|
||||
LuaHeightmap(uint width, uint height);
|
||||
|
||||
virtual ~LuaHeightmap();
|
||||
|
||||
uint getWidth() const;
|
||||
|
||||
uint getHeight() const;
|
||||
|
||||
float* getValues();
|
||||
|
||||
const float* getValues() const;
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
const std::shared_ptr<Heightmap>& getHeightmap() const {
|
||||
return map;
|
||||
}
|
||||
|
||||
fnl_state* getNoise() {
|
||||
return noise.get();
|
||||
}
|
||||
|
||||
void setSeed(int64_t seed);
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "Heightmap";
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaHeightmap>());
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "../lua_util.hpp"
|
||||
#include "lua_type_pcmstream.hpp"
|
||||
#include "assets/Assets.hpp"
|
||||
#include "audio/MemoryPCMStream.hpp"
|
||||
#include "engine/Engine.hpp"
|
||||
|
||||
using namespace lua;
|
||||
using namespace audio;
|
||||
using namespace scripting;
|
||||
|
||||
LuaPCMStream::LuaPCMStream(std::shared_ptr<audio::MemoryPCMStream>&& stream)
|
||||
: stream(std::move(stream)) {
|
||||
}
|
||||
|
||||
LuaPCMStream::~LuaPCMStream() = default;
|
||||
|
||||
const std::shared_ptr<audio::MemoryPCMStream>& LuaPCMStream::getStream() const {
|
||||
return stream;
|
||||
}
|
||||
|
||||
static int l_feed(lua::State* L) {
|
||||
auto stream = touserdata<LuaPCMStream>(L, 1);
|
||||
if (stream == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
auto bytes = bytearray_as_string(L, 2);
|
||||
stream->getStream()->feed(
|
||||
{reinterpret_cast<const ubyte*>(bytes.data()), bytes.size()}
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_share(lua::State* L) {
|
||||
auto stream = touserdata<LuaPCMStream>(L, 1);
|
||||
if (stream == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
auto alias = require_lstring(L, 2);
|
||||
if (engine->isHeadless()) {
|
||||
return 0;
|
||||
}
|
||||
auto assets = engine->getAssets();
|
||||
assets->store<PCMStream>(stream->getStream(), std::string(alias));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_create_sound(lua::State* L) {
|
||||
auto stream = touserdata<LuaPCMStream>(L, 1);
|
||||
if (stream == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
auto alias = require_lstring(L, 2);
|
||||
auto memoryStream = stream->getStream();
|
||||
|
||||
std::vector<char> buffer(memoryStream->available());
|
||||
memoryStream->readFully(buffer.data(), buffer.size(), true);
|
||||
|
||||
auto pcm = std::make_shared<PCM>(
|
||||
std::move(buffer),
|
||||
0,
|
||||
memoryStream->getChannels(),
|
||||
static_cast<uint8_t>(memoryStream->getBitsPerSample()),
|
||||
memoryStream->getSampleRate(),
|
||||
memoryStream->isSeekable()
|
||||
);
|
||||
auto sound = audio::create_sound(std::move(pcm), true);
|
||||
auto assets = engine->getAssets();
|
||||
assets->store<audio::Sound>(std::move(sound), std::string(alias));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::unordered_map<std::string, lua_CFunction> methods {
|
||||
{"feed", lua::wrap<l_feed>},
|
||||
{"share", lua::wrap<l_share>},
|
||||
{"create_sound", lua::wrap<l_create_sound>},
|
||||
};
|
||||
|
||||
static int l_meta_meta_call(lua::State* L) {
|
||||
auto sampleRate = touinteger(L, 2);
|
||||
auto channels = touinteger(L, 3);
|
||||
auto bitsPerSample = touinteger(L, 4);
|
||||
auto stream =
|
||||
std::make_shared<MemoryPCMStream>(sampleRate, channels, bitsPerSample);
|
||||
return newuserdata<LuaPCMStream>(L, std::move(stream));
|
||||
}
|
||||
|
||||
static int l_meta_tostring(lua::State* L) {
|
||||
return pushstring(L, "PCMStream");
|
||||
}
|
||||
|
||||
static int l_meta_index(lua::State* L) {
|
||||
auto stream = touserdata<LuaPCMStream>(L, 1);
|
||||
if (stream == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
if (isstring(L, 2)) {
|
||||
auto found = methods.find(tostring(L, 2));
|
||||
if (found != methods.end()) {
|
||||
return pushcfunction(L, found->second);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaPCMStream::createMetatable(lua::State* L) {
|
||||
createtable(L, 0, 3);
|
||||
pushcfunction(L, lua::wrap<l_meta_tostring>);
|
||||
setfield(L, "__tostring");
|
||||
pushcfunction(L, lua::wrap<l_meta_index>);
|
||||
setfield(L, "__index");
|
||||
|
||||
createtable(L, 0, 1);
|
||||
pushcfunction(L, lua::wrap<l_meta_meta_call>);
|
||||
setfield(L, "__call");
|
||||
setmetatable(L);
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "../lua_commons.hpp"
|
||||
|
||||
namespace audio {
|
||||
class MemoryPCMStream;
|
||||
}
|
||||
|
||||
namespace lua {
|
||||
class LuaPCMStream : public Userdata {
|
||||
public:
|
||||
explicit LuaPCMStream(std::shared_ptr<audio::MemoryPCMStream>&& stream);
|
||||
virtual ~LuaPCMStream() override;
|
||||
|
||||
const std::shared_ptr<audio::MemoryPCMStream>& getStream() const;
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "__vc_PCMStream";
|
||||
private:
|
||||
std::shared_ptr<audio::MemoryPCMStream> stream;
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaPCMStream>());
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../lua_custom_types.hpp"
|
||||
#include "../lua_util.hpp"
|
||||
#include "lua_type_random.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "../lua_commons.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace lua {
|
||||
class LuaRandom : public Userdata {
|
||||
public:
|
||||
std::mt19937 rng;
|
||||
|
||||
explicit LuaRandom(uint64_t seed) : rng(seed) {}
|
||||
virtual ~LuaRandom() override = default;
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "__vc_Random";
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaRandom>());
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "../lua_custom_types.hpp"
|
||||
#include "lua_type_voxelfragment.hpp"
|
||||
|
||||
#include "../lua_util.hpp"
|
||||
|
||||
#include "world/generator/VoxelFragment.hpp"
|
||||
#include "util/stringutil.hpp"
|
||||
#include "world/Level.hpp"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "../lua_commons.hpp"
|
||||
|
||||
class VoxelFragment;
|
||||
|
||||
namespace lua {
|
||||
class LuaVoxelFragment : public Userdata {
|
||||
std::array<std::shared_ptr<VoxelFragment>, 4> fragmentVariants;
|
||||
public:
|
||||
LuaVoxelFragment(
|
||||
std::array<std::shared_ptr<VoxelFragment>, 4> fragmentVariants
|
||||
);
|
||||
|
||||
virtual ~LuaVoxelFragment();
|
||||
|
||||
std::shared_ptr<VoxelFragment> getFragment(size_t rotation) const {
|
||||
return fragmentVariants.at(rotation & 0b11);
|
||||
}
|
||||
|
||||
const std::string& getTypeName() const override {
|
||||
return TYPENAME;
|
||||
}
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "VoxelFragment";
|
||||
};
|
||||
static_assert(!std::is_abstract<LuaVoxelFragment>());
|
||||
}
|
||||
Reference in New Issue
Block a user