mirror of
https://github.com/NoelFB/blah.git
synced 2024-11-25 16:18:57 +08:00
large organizational & cleanup refactor
This commit is contained in:
parent
e65752f30b
commit
e615b9d7e4
|
@ -6,27 +6,23 @@ set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
add_library(blah
|
add_library(blah
|
||||||
|
src/app.cpp
|
||||||
src/core/app.cpp
|
src/filesystem.cpp
|
||||||
src/core/filesystem.cpp
|
src/common.cpp
|
||||||
src/core/common.cpp
|
src/time.cpp
|
||||||
src/core/time.cpp
|
src/input.cpp
|
||||||
|
|
||||||
src/graphics/batch.cpp
|
src/graphics/batch.cpp
|
||||||
src/graphics/blend.cpp
|
src/graphics/blend.cpp
|
||||||
src/graphics/framebuffer.cpp
|
|
||||||
src/graphics/material.cpp
|
src/graphics/material.cpp
|
||||||
src/graphics/mesh.cpp
|
src/graphics/mesh.cpp
|
||||||
src/graphics/renderpass.cpp
|
src/graphics/renderpass.cpp
|
||||||
src/graphics/shader.cpp
|
src/graphics/shader.cpp
|
||||||
src/graphics/spritefont.cpp
|
src/graphics/spritefont.cpp
|
||||||
src/graphics/subtexture.cpp
|
src/graphics/subtexture.cpp
|
||||||
|
src/graphics/target.cpp
|
||||||
src/graphics/texture.cpp
|
src/graphics/texture.cpp
|
||||||
|
|
||||||
src/input/input.cpp
|
|
||||||
src/input/binding.cpp
|
|
||||||
src/input/binding_registry.cpp
|
|
||||||
|
|
||||||
src/containers/str.cpp
|
src/containers/str.cpp
|
||||||
|
|
||||||
src/images/aseprite.cpp
|
src/images/aseprite.cpp
|
||||||
|
@ -34,18 +30,17 @@ add_library(blah
|
||||||
src/images/image.cpp
|
src/images/image.cpp
|
||||||
src/images/packer.cpp
|
src/images/packer.cpp
|
||||||
|
|
||||||
src/math/calc.cpp
|
src/numerics/calc.cpp
|
||||||
src/math/circle.cpp
|
src/numerics/circle.cpp
|
||||||
src/math/color.cpp
|
src/numerics/color.cpp
|
||||||
src/math/line.cpp
|
src/numerics/line.cpp
|
||||||
src/math/mat3x2.cpp
|
src/numerics/mat3x2.cpp
|
||||||
src/math/mat4x4.cpp
|
src/numerics/mat4x4.cpp
|
||||||
src/math/point.cpp
|
src/numerics/point.cpp
|
||||||
src/math/quad.cpp
|
src/numerics/quad.cpp
|
||||||
src/math/rect.cpp
|
src/numerics/rect.cpp
|
||||||
src/math/rectI.cpp
|
src/numerics/rectI.cpp
|
||||||
src/math/stopwatch.cpp
|
src/numerics/vec2.cpp
|
||||||
src/math/vec2.cpp
|
|
||||||
|
|
||||||
src/streams/bufferstream.cpp
|
src/streams/bufferstream.cpp
|
||||||
src/streams/filestream.cpp
|
src/streams/filestream.cpp
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "blah/core/app.h"
|
#include "blah/app.h"
|
||||||
#include "blah/core/filesystem.h"
|
#include "blah/filesystem.h"
|
||||||
#include "blah/core/common.h"
|
#include "blah/common.h"
|
||||||
#include "blah/core/time.h"
|
#include "blah/time.h"
|
||||||
|
#include "blah/input.h"
|
||||||
|
|
||||||
#include "blah/containers/vector.h"
|
#include "blah/containers/vector.h"
|
||||||
#include "blah/containers/stackvector.h"
|
#include "blah/containers/stackvector.h"
|
||||||
|
@ -14,12 +15,12 @@
|
||||||
#include "blah/graphics/subtexture.h"
|
#include "blah/graphics/subtexture.h"
|
||||||
|
|
||||||
#include "blah/graphics/blend.h"
|
#include "blah/graphics/blend.h"
|
||||||
#include "blah/graphics/framebuffer.h"
|
|
||||||
#include "blah/graphics/material.h"
|
#include "blah/graphics/material.h"
|
||||||
#include "blah/graphics/mesh.h"
|
#include "blah/graphics/mesh.h"
|
||||||
#include "blah/graphics/renderpass.h"
|
#include "blah/graphics/renderpass.h"
|
||||||
#include "blah/graphics/sampler.h"
|
#include "blah/graphics/sampler.h"
|
||||||
#include "blah/graphics/shader.h"
|
#include "blah/graphics/shader.h"
|
||||||
|
#include "blah/graphics/target.h"
|
||||||
#include "blah/graphics/texture.h"
|
#include "blah/graphics/texture.h"
|
||||||
|
|
||||||
#include "blah/images/aseprite.h"
|
#include "blah/images/aseprite.h"
|
||||||
|
@ -27,25 +28,21 @@
|
||||||
#include "blah/images/image.h"
|
#include "blah/images/image.h"
|
||||||
#include "blah/images/packer.h"
|
#include "blah/images/packer.h"
|
||||||
|
|
||||||
#include "blah/input/input.h"
|
|
||||||
#include "blah/input/binding.h"
|
|
||||||
#include "blah/input/binding_registry.h"
|
|
||||||
|
|
||||||
#include "blah/math/calc.h"
|
#include "blah/numerics/calc.h"
|
||||||
#include "blah/math/circle.h"
|
#include "blah/numerics/circle.h"
|
||||||
#include "blah/math/color.h"
|
#include "blah/numerics/color.h"
|
||||||
#include "blah/math/ease.h"
|
#include "blah/numerics/ease.h"
|
||||||
#include "blah/math/line.h"
|
#include "blah/numerics/line.h"
|
||||||
#include "blah/math/mat3x2.h"
|
#include "blah/numerics/mat3x2.h"
|
||||||
#include "blah/math/mat4x4.h"
|
#include "blah/numerics/mat4x4.h"
|
||||||
#include "blah/math/point.h"
|
#include "blah/numerics/point.h"
|
||||||
#include "blah/math/quad.h"
|
#include "blah/numerics/quad.h"
|
||||||
#include "blah/math/rect.h"
|
#include "blah/numerics/rect.h"
|
||||||
#include "blah/math/rectI.h"
|
#include "blah/numerics/rectI.h"
|
||||||
#include "blah/math/stopwatch.h"
|
#include "blah/numerics/vec2.h"
|
||||||
#include "blah/math/vec2.h"
|
#include "blah/numerics/vec3.h"
|
||||||
#include "blah/math/vec3.h"
|
#include "blah/numerics/vec4.h"
|
||||||
#include "blah/math/vec4.h"
|
|
||||||
|
|
||||||
#include "blah/streams/bufferstream.h"
|
#include "blah/streams/bufferstream.h"
|
||||||
#include "blah/streams/filestream.h"
|
#include "blah/streams/filestream.h"
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <blah/common.h>
|
||||||
#include <functional>
|
|
||||||
#include <blah/core/common.h>
|
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
// Application Event Functions
|
// Application Event Functions
|
||||||
using AppEventFn = std::function<void()>;
|
using AppEventFn = Func<void()>;
|
||||||
|
|
||||||
// Application Logging Functions
|
// Application Logging Functions
|
||||||
using AppLogFn = std::function<void(const char* message, Log::Category category)>;
|
using AppLogFn = Func<void(const char* message, Log::Category category)>;
|
||||||
|
|
||||||
// Application Configuration
|
// Application Configuration
|
||||||
struct Config
|
struct Config
|
||||||
|
@ -90,8 +88,9 @@ namespace Blah
|
||||||
int max_texture_size = 0;
|
int max_texture_size = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FrameBuffer;
|
// Forward declare Target for the BackBuffer
|
||||||
using FrameBufferRef = std::shared_ptr<FrameBuffer>;
|
class Target;
|
||||||
|
using TargetRef = Ref<Target>;
|
||||||
|
|
||||||
// Application
|
// Application
|
||||||
namespace App
|
namespace App
|
||||||
|
@ -145,6 +144,6 @@ namespace Blah
|
||||||
const RendererFeatures& renderer_features();
|
const RendererFeatures& renderer_features();
|
||||||
|
|
||||||
// Reference to the window's back buffer
|
// Reference to the window's back buffer
|
||||||
extern const FrameBufferRef backbuffer;
|
extern const TargetRef backbuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
56
include/blah/common.h
Normal file
56
include/blah/common.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint> // for integer types
|
||||||
|
#include <cstddef> // for size_t type
|
||||||
|
#include <memory> // for std::shared_ptr
|
||||||
|
#include <functional> // for std::function
|
||||||
|
|
||||||
|
// Asserts
|
||||||
|
#if defined(DEBUG) || defined(_DEBUG)
|
||||||
|
#include <cstdlib> // for abort
|
||||||
|
#define BLAH_ASSERT(condition, msg) \
|
||||||
|
do { if (!(condition)) { Blah::Log::error("%s\n\tin %s:%d", (msg), __FILE__, __LINE__); abort(); } } while(0)
|
||||||
|
#else
|
||||||
|
#define BLAH_ASSERT(condition, msg) \
|
||||||
|
do { if (!(condition)) { Blah::Log::error("%s\n\tin %s:%d", (msg), __FILE__, __LINE__); } } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// maximum length of a print/warn/error message
|
||||||
|
#ifndef BLAH_MESSAGE
|
||||||
|
#define BLAH_MESSAGE 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Blah
|
||||||
|
{
|
||||||
|
using i8 = int8_t;
|
||||||
|
using i16 = int16_t;
|
||||||
|
using i32 = int32_t;
|
||||||
|
using i64 = int64_t;
|
||||||
|
|
||||||
|
using u8 = uint8_t;
|
||||||
|
using u16 = uint16_t;
|
||||||
|
using u32 = uint32_t;
|
||||||
|
using u64 = uint64_t;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using Ref = std::shared_ptr<T>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using WeakRef = std::weak_ptr<T>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using Func = std::function<T>;
|
||||||
|
|
||||||
|
namespace Log
|
||||||
|
{
|
||||||
|
enum class Category
|
||||||
|
{
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error
|
||||||
|
};
|
||||||
|
|
||||||
|
void info(const char* message, ...);
|
||||||
|
void warn(const char* message, ...);
|
||||||
|
void error(const char* message, ...);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace Blah
|
||||||
int m_count;
|
int m_count;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static inline constexpr size_t MaxCapacity = Capacity;
|
static constexpr size_t capacity = Capacity;
|
||||||
|
|
||||||
StackVector();
|
StackVector();
|
||||||
StackVector(const std::initializer_list<T>& init);
|
StackVector(const std::initializer_list<T>& init);
|
||||||
|
@ -30,7 +30,6 @@ namespace Blah
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
int size() const;
|
int size() const;
|
||||||
constexpr int capacity() { return Capacity; }
|
|
||||||
|
|
||||||
T* expand(int amount = 1);
|
T* expand(int amount = 1);
|
||||||
void push_back(const T& item);
|
void push_back(const T& item);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
|
@ -10,6 +10,7 @@ namespace Blah
|
||||||
template<int T>
|
template<int T>
|
||||||
class StrOf;
|
class StrOf;
|
||||||
using String = StrOf<64>;
|
using String = StrOf<64>;
|
||||||
|
using FilePath = StrOf<260>;
|
||||||
|
|
||||||
// A simple String implementation
|
// A simple String implementation
|
||||||
class Str
|
class Str
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <type_traits>
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
@ -104,7 +103,7 @@ namespace Blah
|
||||||
{
|
{
|
||||||
m_buffer = nullptr;
|
m_buffer = nullptr;
|
||||||
m_count = m_capacity = 0;
|
m_count = m_capacity = 0;
|
||||||
reserve(list.size());
|
reserve((int)list.size());
|
||||||
for (auto& it : list)
|
for (auto& it : list)
|
||||||
push_back(std::move(it));
|
push_back(std::move(it));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
// error / abort
|
|
||||||
#if defined(DEBUG) || defined(_DEBUG)
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define BLAH_ERROR(message) \
|
|
||||||
do { Blah::Log::error(message "\n\tin file: %s:%d", __FILE__, __LINE__); abort(); } while(0)
|
|
||||||
|
|
||||||
#define BLAH_ERROR_FMT(message, ...) \
|
|
||||||
do { Blah::Log::error(message "\n\tin file: %s:%d", __VA_ARGS__, __FILE__, __LINE__); abort(); } while(0)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define BLAH_ERROR(message) \
|
|
||||||
Blah::Log::error(message "\n\tin file: %s:%d", __FILE__, __LINE__)
|
|
||||||
|
|
||||||
#define BLAH_ERROR_FMT(message, ...) \
|
|
||||||
Blah::Log::error(message "\n\tin file: %s:%d", __VA_ARGS__, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BLAH_ASSERT(condition, message) \
|
|
||||||
do { if (!(condition)) { BLAH_ERROR(message); } } while(0)
|
|
||||||
|
|
||||||
#define BLAH_ASSERT_FMT(condition, message, ...) \
|
|
||||||
do { if (!(condition)) { BLAH_ERROR_FMT(message, __VA_ARGS__); } } while(0)
|
|
||||||
|
|
||||||
// maximum length of a print/warn/error message
|
|
||||||
#ifndef BLAH_MESSAGE
|
|
||||||
#define BLAH_MESSAGE 1024
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
using i8 = int8_t;
|
|
||||||
using i16 = int16_t;
|
|
||||||
using i32 = int32_t;
|
|
||||||
using i64 = int64_t;
|
|
||||||
|
|
||||||
using u8 = uint8_t;
|
|
||||||
using u16 = uint16_t;
|
|
||||||
using u32 = uint32_t;
|
|
||||||
using u64 = uint64_t;
|
|
||||||
|
|
||||||
namespace Log
|
|
||||||
{
|
|
||||||
enum class Category
|
|
||||||
{
|
|
||||||
Info,
|
|
||||||
Warning,
|
|
||||||
Error
|
|
||||||
};
|
|
||||||
|
|
||||||
void info(const char* message, ...);
|
|
||||||
void warn(const char* message, ...);
|
|
||||||
void error(const char* message, ...);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <blah/common.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
using FilePath = StrOf<265>;
|
class File;
|
||||||
class FileStream;
|
using FileRef = Ref<File>;
|
||||||
|
|
||||||
enum class FileMode
|
enum class FileMode
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,41 @@ namespace Blah
|
||||||
Create,
|
Create,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
File() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Opens a file at the given path.
|
||||||
|
// If it fails, this will return an empty reference.
|
||||||
|
static FileRef open(const FilePath& path, FileMode mode);
|
||||||
|
|
||||||
|
// checks if the given file exists
|
||||||
|
static bool exists(const FilePath& path);
|
||||||
|
|
||||||
|
// deletes the given file
|
||||||
|
static bool destroy(const FilePath& path);
|
||||||
|
|
||||||
|
// Default Destructor
|
||||||
|
virtual ~File() = default;
|
||||||
|
|
||||||
|
// Gets the File Length
|
||||||
|
virtual size_t length() = 0;
|
||||||
|
|
||||||
|
// Gets the current File Position
|
||||||
|
virtual size_t position() = 0;
|
||||||
|
|
||||||
|
// Seeks to the given position in the File
|
||||||
|
virtual size_t seek(size_t position) = 0;
|
||||||
|
|
||||||
|
// Reads from the File into the buffer, and returns how many bytes were successfully read
|
||||||
|
virtual size_t read(unsigned char* buffer, size_t length) = 0;
|
||||||
|
|
||||||
|
// Writes from the buffer into the File, nd returns how many bytes were successfully written
|
||||||
|
virtual size_t write(const unsigned char* buffer, size_t length) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
namespace Directory
|
namespace Directory
|
||||||
{
|
{
|
||||||
// Creates a new directory at the given location.
|
// Creates a new directory at the given location.
|
||||||
|
@ -32,7 +68,7 @@ namespace Blah
|
||||||
bool exists(const FilePath& path);
|
bool exists(const FilePath& path);
|
||||||
|
|
||||||
// Tries to delete a path and returns whether it was successful
|
// Tries to delete a path and returns whether it was successful
|
||||||
bool remove(const FilePath& path);
|
bool destroy(const FilePath& path);
|
||||||
|
|
||||||
// Enumerates over a directory and returns a list of files & directories
|
// Enumerates over a directory and returns a list of files & directories
|
||||||
Vector<FilePath> enumerate(const FilePath& path, bool recursive = true);
|
Vector<FilePath> enumerate(const FilePath& path, bool recursive = true);
|
||||||
|
@ -41,18 +77,6 @@ namespace Blah
|
||||||
void explore(const FilePath& path);
|
void explore(const FilePath& path);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace File
|
|
||||||
{
|
|
||||||
// Checks if the given file exists
|
|
||||||
bool exists(const FilePath& path);
|
|
||||||
|
|
||||||
// Tries to delete a file and returns whether it was successful
|
|
||||||
bool remove(const FilePath& path);
|
|
||||||
|
|
||||||
// Opens the given file and returns a stream
|
|
||||||
FileStream open(const FilePath& path, FileMode mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Path
|
namespace Path
|
||||||
{
|
{
|
||||||
// Returns the file name of the path
|
// Returns the file name of the path
|
|
@ -1,17 +1,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/math/rect.h>
|
#include <blah/numerics/rect.h>
|
||||||
#include <blah/math/mat3x2.h>
|
#include <blah/numerics/mat3x2.h>
|
||||||
#include <blah/math/mat4x4.h>
|
#include <blah/numerics/mat4x4.h>
|
||||||
#include <blah/math/color.h>
|
#include <blah/numerics/color.h>
|
||||||
#include <blah/graphics/subtexture.h>
|
#include <blah/graphics/subtexture.h>
|
||||||
#include <blah/graphics/spritefont.h>
|
#include <blah/graphics/spritefont.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/graphics/blend.h>
|
#include <blah/graphics/blend.h>
|
||||||
#include <blah/graphics/sampler.h>
|
#include <blah/graphics/sampler.h>
|
||||||
#include <blah/graphics/renderpass.h>
|
#include <blah/graphics/renderpass.h>
|
||||||
#include <blah/core/app.h>
|
#include <blah/app.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -125,10 +125,10 @@ namespace Blah
|
||||||
void set_sampler(const TextureSampler& sampler);
|
void set_sampler(const TextureSampler& sampler);
|
||||||
|
|
||||||
// Draws the batch to the given target
|
// Draws the batch to the given target
|
||||||
void render(const FrameBufferRef& target = App::backbuffer);
|
void render(const TargetRef& target = App::backbuffer);
|
||||||
|
|
||||||
// Draws the batch to the given target, with the provided matrix
|
// Draws the batch to the given target, with the provided matrix
|
||||||
void render(const FrameBufferRef& target, const Mat4x4& matrix);
|
void render(const TargetRef& target, const Mat4x4& matrix);
|
||||||
|
|
||||||
// Clears the batch
|
// Clears the batch
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/graphics/texture.h>
|
|
||||||
#include <blah/containers/stackvector.h>
|
|
||||||
#include <blah/math/color.h>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
enum class ClearMask
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Color = 1,
|
|
||||||
Depth = 2,
|
|
||||||
Stencil = 4,
|
|
||||||
All = (int)Color | (int)Depth | (int)Stencil
|
|
||||||
};
|
|
||||||
|
|
||||||
// Up to 4 color attachments + 1 depth/stencil
|
|
||||||
using Attachments = StackVector<TextureRef, 5>;
|
|
||||||
using AttachmentFormats = StackVector<TextureFormat, 5>;
|
|
||||||
|
|
||||||
class FrameBuffer;
|
|
||||||
using FrameBufferRef = std::shared_ptr<FrameBuffer>;
|
|
||||||
|
|
||||||
// FrameBuffer is a 2D Buffer that can be drawn to.
|
|
||||||
// It can hold up to 4 color Textures, and 1 Depth/Stencil Texture.
|
|
||||||
class FrameBuffer
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
FrameBuffer() = default;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Copy / Moves not allowed
|
|
||||||
FrameBuffer(const FrameBuffer&) = delete;
|
|
||||||
FrameBuffer(FrameBuffer&&) = delete;
|
|
||||||
FrameBuffer& operator=(const FrameBuffer&) = delete;
|
|
||||||
FrameBuffer& operator=(FrameBuffer&&) = delete;
|
|
||||||
|
|
||||||
// Default Destructor
|
|
||||||
virtual ~FrameBuffer() = default;
|
|
||||||
|
|
||||||
// Creates a new FrameBuffer with a single Color attachment
|
|
||||||
// If the FrameBuffer creation fails, it will return an invalid FrameBufferRef.
|
|
||||||
static FrameBufferRef create(int width, int height);
|
|
||||||
|
|
||||||
// Creates a new FrameBuffer with the given Texture Attachments. You must provide at least one Attachment.
|
|
||||||
// If the FrameBuffer creation fails, it will return an invalid FrameBufferRef.
|
|
||||||
static FrameBufferRef create(int width, int height, const AttachmentFormats& attachments);
|
|
||||||
|
|
||||||
// Gets the list of Attachments from the FrameBuffer
|
|
||||||
virtual Attachments& attachments() = 0;
|
|
||||||
|
|
||||||
// Gets the list of Attachments from the FrameBuffer
|
|
||||||
virtual const Attachments& attachments() const = 0;
|
|
||||||
|
|
||||||
// Gets the Attachment at a given index from the FrameBuffer
|
|
||||||
TextureRef& attachment(int index);
|
|
||||||
|
|
||||||
// Gets the Attachment at a given index from the FrameBuffer
|
|
||||||
const TextureRef& attachment(int index) const;
|
|
||||||
|
|
||||||
// Gets the width of the FrameBuffer
|
|
||||||
virtual int width() const;
|
|
||||||
|
|
||||||
// Gets the height of the FrameBuffer
|
|
||||||
virtual int height() const;
|
|
||||||
|
|
||||||
// Clears the FrameBuffer
|
|
||||||
virtual void clear(Color color = Color::black, float depth = 1.0f, u8 stencil = 0, ClearMask mask = ClearMask::All) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,14 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <blah/common.h>
|
||||||
#include <blah/graphics/texture.h>
|
#include <blah/graphics/texture.h>
|
||||||
#include <blah/graphics/shader.h>
|
#include <blah/graphics/shader.h>
|
||||||
#include <blah/graphics/sampler.h>
|
#include <blah/graphics/sampler.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
class Material;
|
class Material;
|
||||||
typedef std::shared_ptr<Material> MaterialRef;
|
using MaterialRef = Ref<Material>;
|
||||||
|
|
||||||
// Materials hold values that can be assigned to a shader during rendering
|
// Materials hold values that can be assigned to a shader during rendering
|
||||||
class Material final
|
class Material final
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <memory>
|
|
||||||
#include <blah/containers/stackvector.h>
|
#include <blah/containers/stackvector.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
|
@ -59,7 +58,7 @@ namespace Blah
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mesh;
|
class Mesh;
|
||||||
typedef std::shared_ptr<Mesh> MeshRef;
|
using MeshRef = Ref<Mesh>;
|
||||||
|
|
||||||
// A Mesh is a set of Indices and Vertices which are used for drawing
|
// A Mesh is a set of Indices and Vertices which are used for drawing
|
||||||
class Mesh
|
class Mesh
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/math/rect.h>
|
#include <blah/numerics/rect.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/graphics/texture.h>
|
#include <blah/graphics/texture.h>
|
||||||
#include <blah/graphics/framebuffer.h>
|
#include <blah/graphics/target.h>
|
||||||
#include <blah/graphics/mesh.h>
|
#include <blah/graphics/mesh.h>
|
||||||
#include <blah/graphics/shader.h>
|
#include <blah/graphics/shader.h>
|
||||||
#include <blah/graphics/material.h>
|
#include <blah/graphics/material.h>
|
||||||
|
@ -42,7 +42,7 @@ namespace Blah
|
||||||
struct RenderPass
|
struct RenderPass
|
||||||
{
|
{
|
||||||
// Framebuffer to draw to
|
// Framebuffer to draw to
|
||||||
FrameBufferRef target;
|
TargetRef target;
|
||||||
|
|
||||||
// Mesh to draw with
|
// Mesh to draw with
|
||||||
MeshRef mesh;
|
MeshRef mesh;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <blah/common.h>
|
||||||
#include <blah/containers/stackvector.h>
|
#include <blah/containers/stackvector.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -70,7 +70,7 @@ namespace Blah
|
||||||
};
|
};
|
||||||
|
|
||||||
class Shader;
|
class Shader;
|
||||||
typedef std::shared_ptr<Shader> ShaderRef;
|
using ShaderRef = Ref<Shader>;
|
||||||
|
|
||||||
// A shader used during Rendering
|
// A shader used during Rendering
|
||||||
class Shader
|
class Shader
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/graphics/subtexture.h>
|
#include <blah/graphics/subtexture.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/graphics/texture.h>
|
#include <blah/graphics/texture.h>
|
||||||
#include <blah/math/rect.h>
|
#include <blah/numerics/rect.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
72
include/blah/graphics/target.h
Normal file
72
include/blah/graphics/target.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
#pragma once
|
||||||
|
#include <blah/common.h>
|
||||||
|
#include <blah/graphics/texture.h>
|
||||||
|
#include <blah/containers/stackvector.h>
|
||||||
|
#include <blah/numerics/color.h>
|
||||||
|
|
||||||
|
namespace Blah
|
||||||
|
{
|
||||||
|
enum class ClearMask
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Color = 1,
|
||||||
|
Depth = 2,
|
||||||
|
Stencil = 4,
|
||||||
|
All = (int)Color | (int)Depth | (int)Stencil
|
||||||
|
};
|
||||||
|
|
||||||
|
// Up to 4 color textures + 1 depth/stencil
|
||||||
|
using Attachments = StackVector<TextureRef, 5>;
|
||||||
|
using AttachmentFormats = StackVector<TextureFormat, 5>;
|
||||||
|
|
||||||
|
class Target;
|
||||||
|
using TargetRef = Ref<Target>;
|
||||||
|
|
||||||
|
// Target is a 2D Buffer that can be drawn to.
|
||||||
|
// It can hold up to 4 color Textures, and 1 Depth/Stencil Texture.
|
||||||
|
class Target
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Target() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Copy / Moves not allowed
|
||||||
|
Target(const Target&) = delete;
|
||||||
|
Target(Target&&) = delete;
|
||||||
|
Target& operator=(const Target&) = delete;
|
||||||
|
Target& operator=(Target&&) = delete;
|
||||||
|
|
||||||
|
// Default Destructor
|
||||||
|
virtual ~Target() = default;
|
||||||
|
|
||||||
|
// Creates a new Target with a single Color texture
|
||||||
|
// If the Target creation fails, it will return an invalid TargetRef.
|
||||||
|
static TargetRef create(int width, int height);
|
||||||
|
|
||||||
|
// Creates a new Target with the given Texture Attachments. You must provide at least one Attachment.
|
||||||
|
// If the Target creation fails, it will return an invalid TargetRef.
|
||||||
|
static TargetRef create(int width, int height, const AttachmentFormats& textures);
|
||||||
|
|
||||||
|
// Gets the list of Attachments from the Target
|
||||||
|
virtual Attachments& textures() = 0;
|
||||||
|
|
||||||
|
// Gets the list of Attachments from the Target
|
||||||
|
virtual const Attachments& textures() const = 0;
|
||||||
|
|
||||||
|
// Gets the Attachment at a given index from the Target
|
||||||
|
TextureRef& texture(int index);
|
||||||
|
|
||||||
|
// Gets the Attachment at a given index from the Target
|
||||||
|
const TextureRef& texture(int index) const;
|
||||||
|
|
||||||
|
// Gets the width of the Target
|
||||||
|
virtual int width() const;
|
||||||
|
|
||||||
|
// Gets the height of the Target
|
||||||
|
virtual int height() const;
|
||||||
|
|
||||||
|
// Clears the Target
|
||||||
|
virtual void clear(Color color = Color::black, float depth = 1.0f, u8 stencil = 0, ClearMask mask = ClearMask::All) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <blah/common.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ namespace Blah
|
||||||
class Image;
|
class Image;
|
||||||
class Stream;
|
class Stream;
|
||||||
class Texture;
|
class Texture;
|
||||||
typedef std::shared_ptr<Texture> TextureRef;
|
using TextureRef = Ref<Texture>;
|
||||||
|
|
||||||
// A 2D Texture held by the GPU to be used during rendering
|
// A 2D Texture held by the GPU to be used during rendering
|
||||||
class Texture
|
class Texture
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/color.h>
|
#include <blah/numerics/color.h>
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/streams/stream.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/streams/stream.h>
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/color.h>
|
#include <blah/numerics/color.h>
|
||||||
#include <blah/math/rectI.h>
|
#include <blah/numerics/rectI.h>
|
||||||
#include <blah/math/point.h>
|
#include <blah/numerics/point.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/math/color.h>
|
#include <blah/numerics/color.h>
|
||||||
#include <blah/math/rectI.h>
|
#include <blah/numerics/rectI.h>
|
||||||
#include <blah/math/point.h>
|
#include <blah/numerics/point.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
#include <blah/streams/bufferstream.h>
|
#include <blah/streams/bufferstream.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
|
#include <blah/containers/stackvector.h>
|
||||||
|
|
||||||
// These are generally copied from the SDL2 Scancode Keys,
|
// These are generally copied from the SDL2 Scancode Keys,
|
||||||
// which are in turn based on the USB standards:
|
// which are in turn based on the USB standards:
|
||||||
|
@ -345,6 +346,306 @@ namespace Blah
|
||||||
Right = 2,
|
Right = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class InputBinding;
|
||||||
|
using InputBindingRef = Ref<InputBinding>;
|
||||||
|
|
||||||
|
class AxisBinding;
|
||||||
|
using AxisBindingRef = Ref<AxisBinding>;
|
||||||
|
|
||||||
|
class StickBinding;
|
||||||
|
using StickBindingRef = Ref<StickBinding>;
|
||||||
|
|
||||||
|
// Single input Binding
|
||||||
|
// You must call Binding::update() every frame to poll the input state.
|
||||||
|
// Alternatively, bindings can be registered to Input which will
|
||||||
|
// automatically update them.
|
||||||
|
class InputBinding
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Represents a Controller Trigger or a single direction of a Controller Axis.
|
||||||
|
struct TriggerBind
|
||||||
|
{
|
||||||
|
// Controller Index we're bound to
|
||||||
|
int controller = 0;
|
||||||
|
|
||||||
|
// The Axis we're bound to
|
||||||
|
Axis axis = Axis::None;
|
||||||
|
|
||||||
|
// Minimum value of the axis
|
||||||
|
float threshold = 0.01f;
|
||||||
|
|
||||||
|
// requires a positive value
|
||||||
|
// otherwise requires a negative value
|
||||||
|
bool positive = true;
|
||||||
|
|
||||||
|
TriggerBind() = default;
|
||||||
|
TriggerBind(Axis axis);
|
||||||
|
TriggerBind(int controller, Axis axis, float threshold, bool positive);
|
||||||
|
|
||||||
|
bool is_down(float axis_value) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Represents a Controller Button.
|
||||||
|
struct ButtonBind
|
||||||
|
{
|
||||||
|
// Controller Index we're bound to
|
||||||
|
int controller = 0;
|
||||||
|
|
||||||
|
// Button we're bound to
|
||||||
|
Button button = Button::None;
|
||||||
|
|
||||||
|
ButtonBind() = default;
|
||||||
|
ButtonBind(Button button);
|
||||||
|
ButtonBind(int controller, Button button);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Input Buffer for press events
|
||||||
|
float press_buffer = 0;
|
||||||
|
|
||||||
|
// Input Buffer for release events
|
||||||
|
float release_buffer = 0;
|
||||||
|
|
||||||
|
// List of bound Keys
|
||||||
|
StackVector<Key, 16> keys;
|
||||||
|
|
||||||
|
// List of bound Buttons
|
||||||
|
StackVector<ButtonBind, 16> buttons;
|
||||||
|
|
||||||
|
// List of bound Triggers / Axis
|
||||||
|
StackVector<TriggerBind, 16> triggers;
|
||||||
|
|
||||||
|
// List of bound Mouse buttons
|
||||||
|
StackVector<MouseButton, 16> mouse;
|
||||||
|
|
||||||
|
InputBinding() = default;
|
||||||
|
|
||||||
|
InputBinding(float press_buffer)
|
||||||
|
: press_buffer(press_buffer)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ... Args>
|
||||||
|
InputBinding(float press_buffer, const Args&... args)
|
||||||
|
: press_buffer(press_buffer)
|
||||||
|
{
|
||||||
|
add(args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the binding has been pressed
|
||||||
|
bool pressed() const;
|
||||||
|
|
||||||
|
// if the binding has been released
|
||||||
|
bool released() const;
|
||||||
|
|
||||||
|
// if the binding is currently held
|
||||||
|
bool down() const;
|
||||||
|
|
||||||
|
// returns the binding's value from 0-1
|
||||||
|
float value() const;
|
||||||
|
|
||||||
|
// returns the bindings signed value (0 or 1)
|
||||||
|
int sign() const;
|
||||||
|
|
||||||
|
// returns the timestamp of the last time the binding was pressed
|
||||||
|
double timestamp() const;
|
||||||
|
|
||||||
|
// updates the binding state
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// consumes the current press, and pressed() will return false until the next press
|
||||||
|
void consume_press();
|
||||||
|
|
||||||
|
// consumes the current release, and released() will return false until the next release
|
||||||
|
void consume_release();
|
||||||
|
|
||||||
|
// adds a key to the binding
|
||||||
|
InputBinding& add(Key key);
|
||||||
|
|
||||||
|
// adds a button to the binding
|
||||||
|
InputBinding& add(ButtonBind button);
|
||||||
|
|
||||||
|
// adds an trigger to the binding
|
||||||
|
InputBinding& add(TriggerBind trigger);
|
||||||
|
|
||||||
|
// adds a mouse button to the binding
|
||||||
|
InputBinding& add(MouseButton mouse);
|
||||||
|
|
||||||
|
// adds an input to the binding
|
||||||
|
template<typename T, typename T2, typename ... Args>
|
||||||
|
InputBinding& add(T first, T2 second, const Args&... args)
|
||||||
|
{
|
||||||
|
add(first);
|
||||||
|
add(second, args...);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// adds the left trigger to the binding
|
||||||
|
InputBinding& add_left_trigger(int controller, float threshold);
|
||||||
|
|
||||||
|
// adds the right trigger to the binding
|
||||||
|
InputBinding& add_right_trigger(int controller, float threshold);
|
||||||
|
|
||||||
|
// assigns all the bindings to the specific controller
|
||||||
|
InputBinding& set_controller(int index);
|
||||||
|
|
||||||
|
// removes all bindings
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_last_timestamp = 0;
|
||||||
|
double m_last_press_time = -1;
|
||||||
|
double m_last_release_time = -1;
|
||||||
|
float m_value = 0.0f;
|
||||||
|
bool m_pressed = false;
|
||||||
|
bool m_released = false;
|
||||||
|
bool m_down = false;
|
||||||
|
bool m_press_consumed = false;
|
||||||
|
bool m_release_consumed = false;
|
||||||
|
|
||||||
|
bool get_pressed() const;
|
||||||
|
bool get_released() const;
|
||||||
|
bool get_down() const;
|
||||||
|
float get_value() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Axis Binding (ex. Left/Right movement, or a Trigger)
|
||||||
|
// You must call AxisBinding::update() every frame to poll the input state.
|
||||||
|
// Alternatively, bindings can be registered to Input which will
|
||||||
|
// automatically update them.
|
||||||
|
class AxisBinding
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum class Overlap
|
||||||
|
{
|
||||||
|
Newer,
|
||||||
|
Older,
|
||||||
|
Cancel
|
||||||
|
};
|
||||||
|
|
||||||
|
// Negative Value Binding
|
||||||
|
InputBinding negative;
|
||||||
|
|
||||||
|
// Positive Value Binding
|
||||||
|
InputBinding positive;
|
||||||
|
|
||||||
|
// How to handle overlaps (ex. Left and Right are both held)
|
||||||
|
Overlap overlap = Overlap::Newer;
|
||||||
|
|
||||||
|
AxisBinding() = default;
|
||||||
|
|
||||||
|
AxisBinding(const InputBinding& negative, const InputBinding& positive, Overlap overlap = Overlap::Newer)
|
||||||
|
: negative(negative)
|
||||||
|
, positive(positive)
|
||||||
|
, overlap(overlap)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Current Value from -1 to 1
|
||||||
|
float value() const;
|
||||||
|
|
||||||
|
// Current value, either -1, 0, or 1
|
||||||
|
int sign() const;
|
||||||
|
|
||||||
|
// updates the Binding
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// consumes the press buffer
|
||||||
|
void consume_press();
|
||||||
|
|
||||||
|
// consumes the release buffer
|
||||||
|
void consume_release();
|
||||||
|
|
||||||
|
// Adds a negative & positive binding pair
|
||||||
|
template<typename NegativeT, typename PositiveT>
|
||||||
|
AxisBinding& add(NegativeT negative, PositiveT positive)
|
||||||
|
{
|
||||||
|
this->negative.add(negative);
|
||||||
|
this->positive.add(positive);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a Stick binding
|
||||||
|
AxisBinding& add_left_stick_x(int controller, float threshold);
|
||||||
|
AxisBinding& add_left_stick_y(int controller, float threshold);
|
||||||
|
AxisBinding& add_right_stick_x(int controller, float threshold);
|
||||||
|
AxisBinding& add_right_stick_y(int controller, float threshold);
|
||||||
|
|
||||||
|
// assigns all the bindings to the specific controller
|
||||||
|
AxisBinding& set_controller(int index);
|
||||||
|
|
||||||
|
// Clears all Bindings
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Stick Binding (ex. Joystick, Dpad, Arrow Keys, WASD, etc)
|
||||||
|
// You must call StickBinding::update() every frame to poll the input state.
|
||||||
|
// Alternatively, bindings can be registered to Input which will
|
||||||
|
// automatically update them.
|
||||||
|
class StickBinding
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// X Axis Binding
|
||||||
|
AxisBinding x;
|
||||||
|
|
||||||
|
// Y Axis Binding
|
||||||
|
AxisBinding y;
|
||||||
|
|
||||||
|
// An optional threshold for circular thresholds
|
||||||
|
float round_threshold = 0.0f;
|
||||||
|
|
||||||
|
StickBinding() = default;
|
||||||
|
|
||||||
|
StickBinding(const AxisBinding& x, const AxisBinding& y, float round_threshold = 0)
|
||||||
|
: x(x)
|
||||||
|
, y(y)
|
||||||
|
, round_threshold(round_threshold)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Current Value, -1 to 1
|
||||||
|
Vec2 value() const;
|
||||||
|
|
||||||
|
// Current value, either -1, 0, or 1
|
||||||
|
Point sign() const;
|
||||||
|
|
||||||
|
// Updates the Binding
|
||||||
|
void update();
|
||||||
|
|
||||||
|
// Consumes the Press Buffer
|
||||||
|
void consume_press();
|
||||||
|
|
||||||
|
// Consumes the Release Buffer
|
||||||
|
void consume_release();
|
||||||
|
|
||||||
|
// Adds directional bindings
|
||||||
|
template<typename LeftT, typename RightT, typename UpT, typename DownT>
|
||||||
|
StickBinding& add(LeftT left, RightT right, UpT up, DownT down)
|
||||||
|
{
|
||||||
|
x.negative.add(left);
|
||||||
|
x.positive.add(right);
|
||||||
|
y.negative.add(up);
|
||||||
|
y.positive.add(down);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds the dpad binding
|
||||||
|
StickBinding& add_dpad(int controller);
|
||||||
|
|
||||||
|
// Adds the left stick binding
|
||||||
|
StickBinding& add_left_stick(int controller, float threshold);
|
||||||
|
|
||||||
|
// Adds the right stick binding
|
||||||
|
StickBinding& add_right_stick(int controller, float threshold);
|
||||||
|
|
||||||
|
// assigns all the bindings to the specific controller
|
||||||
|
StickBinding& set_controller(int index);
|
||||||
|
|
||||||
|
// Clears all the bindings
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
|
||||||
namespace Input
|
namespace Input
|
||||||
{
|
{
|
||||||
// Returns the Input State of the current frame.
|
// Returns the Input State of the current frame.
|
||||||
|
@ -427,5 +728,14 @@ namespace Blah
|
||||||
|
|
||||||
// returns a string name of the given button
|
// returns a string name of the given button
|
||||||
const char* name_of(Button button);
|
const char* name_of(Button button);
|
||||||
|
|
||||||
|
// registers a new binding
|
||||||
|
InputBindingRef register_binding(const InputBinding& binding);
|
||||||
|
|
||||||
|
// registers a new axis binding
|
||||||
|
AxisBindingRef register_binding(const AxisBinding& binding);
|
||||||
|
|
||||||
|
// registers a new stick binding
|
||||||
|
StickBindingRef register_binding(const StickBinding& binding);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,299 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/input/input.h>
|
|
||||||
#include <blah/containers/stackvector.h>
|
|
||||||
#include <blah/math/point.h>
|
|
||||||
#include <blah/math/vec2.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
// Single input Binding
|
|
||||||
// You must call Binding::update() every frame to poll the input state.
|
|
||||||
// Alternatively, bindings can be registered to BindingRegistry which will
|
|
||||||
// automatically update them.
|
|
||||||
class Binding
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Represents a Controller Trigger or a single direction of a Controller Axis.
|
|
||||||
struct TriggerBind
|
|
||||||
{
|
|
||||||
// Controller Index we're bound to
|
|
||||||
int controller = 0;
|
|
||||||
|
|
||||||
// The Axis we're bound to
|
|
||||||
Axis axis = Axis::None;
|
|
||||||
|
|
||||||
// Minimum value of the axis
|
|
||||||
float threshold = 0.01f;
|
|
||||||
|
|
||||||
// requires a positive value
|
|
||||||
// otherwise requires a negative value
|
|
||||||
bool positive = true;
|
|
||||||
|
|
||||||
TriggerBind() = default;
|
|
||||||
TriggerBind(Axis axis);
|
|
||||||
TriggerBind(int controller, Axis axis, float threshold, bool positive);
|
|
||||||
|
|
||||||
bool is_down(float axis_value) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Represents a Controller Button.
|
|
||||||
struct ButtonBind
|
|
||||||
{
|
|
||||||
// Controller Index we're bound to
|
|
||||||
int controller = 0;
|
|
||||||
|
|
||||||
// Button we're bound to
|
|
||||||
Button button = Button::None;
|
|
||||||
|
|
||||||
ButtonBind() = default;
|
|
||||||
ButtonBind(Button button);
|
|
||||||
ButtonBind(int controller, Button button);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Input Buffer for press events
|
|
||||||
float press_buffer = 0;
|
|
||||||
|
|
||||||
// Input Buffer for release events
|
|
||||||
float release_buffer = 0;
|
|
||||||
|
|
||||||
// List of bound Keys
|
|
||||||
StackVector<Key, 16> keys;
|
|
||||||
|
|
||||||
// List of bound Buttons
|
|
||||||
StackVector<ButtonBind, 16> buttons;
|
|
||||||
|
|
||||||
// List of bound Triggers / Axis
|
|
||||||
StackVector<TriggerBind, 16> triggers;
|
|
||||||
|
|
||||||
// List of bound Mouse buttons
|
|
||||||
StackVector<MouseButton, 16> mouse;
|
|
||||||
|
|
||||||
Binding() = default;
|
|
||||||
|
|
||||||
Binding(float press_buffer)
|
|
||||||
: press_buffer(press_buffer)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ... Args>
|
|
||||||
Binding(float press_buffer, const Args&... args)
|
|
||||||
: press_buffer(press_buffer)
|
|
||||||
{
|
|
||||||
add(args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the binding has been pressed
|
|
||||||
bool pressed() const;
|
|
||||||
|
|
||||||
// if the binding has been released
|
|
||||||
bool released() const;
|
|
||||||
|
|
||||||
// if the binding is currently held
|
|
||||||
bool down() const;
|
|
||||||
|
|
||||||
// returns the binding's value from 0-1
|
|
||||||
float value() const;
|
|
||||||
|
|
||||||
// returns the bindings signed value (0 or 1)
|
|
||||||
int sign() const;
|
|
||||||
|
|
||||||
// returns the timestamp of the last time the binding was pressed
|
|
||||||
double timestamp() const;
|
|
||||||
|
|
||||||
// updates the binding state
|
|
||||||
void update();
|
|
||||||
|
|
||||||
// consumes the current press, and pressed() will return false until the next press
|
|
||||||
void consume_press();
|
|
||||||
|
|
||||||
// consumes the current release, and released() will return false until the next release
|
|
||||||
void consume_release();
|
|
||||||
|
|
||||||
// adds a key to the binding
|
|
||||||
Binding& add(Key key);
|
|
||||||
|
|
||||||
// adds a button to the binding
|
|
||||||
Binding& add(ButtonBind button);
|
|
||||||
|
|
||||||
// adds an trigger to the binding
|
|
||||||
Binding& add(TriggerBind trigger);
|
|
||||||
|
|
||||||
// adds a mouse button to the binding
|
|
||||||
Binding& add(MouseButton mouse);
|
|
||||||
|
|
||||||
// adds an input to the binding
|
|
||||||
template<typename T, typename T2, typename ... Args>
|
|
||||||
Binding& add(T first, T2 second, const Args&... args)
|
|
||||||
{
|
|
||||||
add(first);
|
|
||||||
add(second, args...);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// adds the left trigger to the binding
|
|
||||||
Binding& add_left_trigger(int controller, float threshold);
|
|
||||||
|
|
||||||
// adds the right trigger to the binding
|
|
||||||
Binding& add_right_trigger(int controller, float threshold);
|
|
||||||
|
|
||||||
// assigns all the bindings to the specific controller
|
|
||||||
Binding& set_controller(int index);
|
|
||||||
|
|
||||||
// removes all bindings
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
private:
|
|
||||||
double m_last_timestamp = 0;
|
|
||||||
double m_last_press_time = -1;
|
|
||||||
double m_last_release_time = -1;
|
|
||||||
float m_value = 0.0f;
|
|
||||||
bool m_pressed = false;
|
|
||||||
bool m_released = false;
|
|
||||||
bool m_down = false;
|
|
||||||
bool m_press_consumed = false;
|
|
||||||
bool m_release_consumed = false;
|
|
||||||
|
|
||||||
bool get_pressed() const;
|
|
||||||
bool get_released() const;
|
|
||||||
bool get_down() const;
|
|
||||||
float get_value() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Axis Binding (ex. Left/Right movement, or a Trigger)
|
|
||||||
// You must call AxisBinding::update() every frame to poll the input state.
|
|
||||||
// Alternatively, bindings can be registered to BindingRegistry which will
|
|
||||||
// automatically update them.
|
|
||||||
class AxisBinding
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum class Overlap
|
|
||||||
{
|
|
||||||
Newer,
|
|
||||||
Older,
|
|
||||||
Cancel
|
|
||||||
};
|
|
||||||
|
|
||||||
// Negative Value Binding
|
|
||||||
Binding negative;
|
|
||||||
|
|
||||||
// Positive Value Binding
|
|
||||||
Binding positive;
|
|
||||||
|
|
||||||
// How to handle overlaps (ex. Left and Right are both held)
|
|
||||||
Overlap overlap = Overlap::Newer;
|
|
||||||
|
|
||||||
AxisBinding() = default;
|
|
||||||
|
|
||||||
AxisBinding(const Binding& negative, const Binding& positive, Overlap overlap = Overlap::Newer)
|
|
||||||
: negative(negative)
|
|
||||||
, positive(positive)
|
|
||||||
, overlap(overlap)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Current Value from -1 to 1
|
|
||||||
float value() const;
|
|
||||||
|
|
||||||
// Current value, either -1, 0, or 1
|
|
||||||
int sign() const;
|
|
||||||
|
|
||||||
// updates the Binding
|
|
||||||
void update();
|
|
||||||
|
|
||||||
// consumes the press buffer
|
|
||||||
void consume_press();
|
|
||||||
|
|
||||||
// consumes the release buffer
|
|
||||||
void consume_release();
|
|
||||||
|
|
||||||
// Adds a negative & positive binding pair
|
|
||||||
template<typename NegativeT, typename PositiveT>
|
|
||||||
AxisBinding& add(NegativeT negative, PositiveT positive)
|
|
||||||
{
|
|
||||||
this->negative.add(negative);
|
|
||||||
this->positive.add(positive);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a Stick binding
|
|
||||||
AxisBinding& add_left_stick_x(int controller, float threshold);
|
|
||||||
AxisBinding& add_left_stick_y(int controller, float threshold);
|
|
||||||
AxisBinding& add_right_stick_x(int controller, float threshold);
|
|
||||||
AxisBinding& add_right_stick_y(int controller, float threshold);
|
|
||||||
|
|
||||||
// assigns all the bindings to the specific controller
|
|
||||||
AxisBinding& set_controller(int index);
|
|
||||||
|
|
||||||
// Clears all Bindings
|
|
||||||
void clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Stick Binding (ex. Joystick, Dpad, Arrow Keys, WASD, etc)
|
|
||||||
// You must call StickBinding::update() every frame to poll the input state.
|
|
||||||
// Alternatively, bindings can be registered to BindingRegistry which will
|
|
||||||
// automatically update them.
|
|
||||||
class StickBinding
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// X Axis Binding
|
|
||||||
AxisBinding x;
|
|
||||||
|
|
||||||
// Y Axis Binding
|
|
||||||
AxisBinding y;
|
|
||||||
|
|
||||||
// An optional threshold for circular thresholds
|
|
||||||
float round_threshold = 0.0f;
|
|
||||||
|
|
||||||
StickBinding() = default;
|
|
||||||
|
|
||||||
StickBinding(const AxisBinding& x, const AxisBinding& y, float round_threshold = 0)
|
|
||||||
: x(x)
|
|
||||||
, y(y)
|
|
||||||
, round_threshold(round_threshold)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// Current Value, -1 to 1
|
|
||||||
Vec2 value() const;
|
|
||||||
|
|
||||||
// Current value, either -1, 0, or 1
|
|
||||||
Point sign() const;
|
|
||||||
|
|
||||||
// Updates the Binding
|
|
||||||
void update();
|
|
||||||
|
|
||||||
// Consumes the Press Buffer
|
|
||||||
void consume_press();
|
|
||||||
|
|
||||||
// Consumes the Release Buffer
|
|
||||||
void consume_release();
|
|
||||||
|
|
||||||
// Adds directional bindings
|
|
||||||
template<typename LeftT, typename RightT, typename UpT, typename DownT>
|
|
||||||
StickBinding& add(LeftT left, RightT right, UpT up, DownT down)
|
|
||||||
{
|
|
||||||
x.negative.add(left);
|
|
||||||
x.positive.add(right);
|
|
||||||
y.negative.add(up);
|
|
||||||
y.positive.add(down);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds the dpad binding
|
|
||||||
StickBinding& add_dpad(int controller);
|
|
||||||
|
|
||||||
// Adds the left stick binding
|
|
||||||
StickBinding& add_left_stick(int controller, float threshold);
|
|
||||||
|
|
||||||
// Adds the right stick binding
|
|
||||||
StickBinding& add_right_stick(int controller, float threshold);
|
|
||||||
|
|
||||||
// assigns all the bindings to the specific controller
|
|
||||||
StickBinding& set_controller(int index);
|
|
||||||
|
|
||||||
// Clears all the bindings
|
|
||||||
void clear();
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/input/binding.h>
|
|
||||||
#include <blah/containers/vector.h>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
using BindingRef = std::shared_ptr<Binding>;
|
|
||||||
using AxisBindingRef = std::shared_ptr<AxisBinding>;
|
|
||||||
using StickBindingRef = std::shared_ptr<StickBinding>;
|
|
||||||
|
|
||||||
// An Optional registry to automatically update Input Bindings.
|
|
||||||
// Once registered here, you do not need to explicitely call their update methods.
|
|
||||||
class BindingRegistry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// registers a new binding
|
|
||||||
static BindingRef register_binding(const Binding& binding = Binding());
|
|
||||||
|
|
||||||
// registers a new axis binding
|
|
||||||
static AxisBindingRef register_axis(const AxisBinding& binding = AxisBinding());
|
|
||||||
|
|
||||||
// registers a new stick binding
|
|
||||||
static StickBindingRef register_stick(const StickBinding& binding = StickBinding());
|
|
||||||
|
|
||||||
// updates all the bindings. This is called
|
|
||||||
// automatically by the App loop.
|
|
||||||
static void update();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static Vector<std::weak_ptr<Binding>> bindings;
|
|
||||||
static Vector<std::weak_ptr<AxisBinding>> axes;
|
|
||||||
static Vector<std::weak_ptr<StickBinding>> sticks;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <blah/core/common.h>
|
|
||||||
|
|
||||||
namespace Blah
|
|
||||||
{
|
|
||||||
class Stopwatch
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Stopwatch();
|
|
||||||
void reset();
|
|
||||||
u64 microseconds();
|
|
||||||
u64 milliseconds();
|
|
||||||
private:
|
|
||||||
u64 start_time;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -289,7 +289,7 @@ namespace Blah
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLAH_ERROR("Invalid Easer Type");
|
BLAH_ASSERT(false, "Invalid Easer Type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -1,8 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/point.h>
|
#include <blah/numerics/point.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/math/rectI.h>
|
#include <blah/numerics/rectI.h>
|
||||||
#include <blah/math/line.h>
|
#include <blah/numerics/line.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/math/point.h>
|
#include <blah/numerics/point.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -12,28 +12,28 @@ namespace Blah
|
||||||
BufferStream& operator=(BufferStream&& bs) noexcept;
|
BufferStream& operator=(BufferStream&& bs) noexcept;
|
||||||
~BufferStream();
|
~BufferStream();
|
||||||
|
|
||||||
virtual i64 length() const override { return m_length; }
|
virtual size_t length() const override { return m_length; }
|
||||||
virtual i64 position() const override { return m_position; }
|
virtual size_t position() const override { return m_position; }
|
||||||
virtual i64 seek(i64 seekTo) override { return m_position = (seekTo < 0 ? 0 : (seekTo > m_length ? m_length : seekTo)); }
|
virtual size_t seek(size_t seekTo) override { return m_position = (seekTo < 0 ? 0 : (seekTo > m_length ? m_length : seekTo)); }
|
||||||
virtual bool is_open() const override { return m_buffer != nullptr; }
|
virtual bool is_open() const override { return m_buffer != nullptr; }
|
||||||
virtual bool is_readable() const override { return true; }
|
virtual bool is_readable() const override { return true; }
|
||||||
virtual bool is_writable() const override { return true; }
|
virtual bool is_writable() const override { return true; }
|
||||||
virtual void close() override;
|
virtual void close() override;
|
||||||
|
|
||||||
void resize(i64 length);
|
void resize(size_t length);
|
||||||
void clear() { m_length = m_position = 0; }
|
void clear() { m_length = m_position = 0; }
|
||||||
|
|
||||||
char* data() { return m_buffer; }
|
char* data() { return m_buffer; }
|
||||||
const char* data() const { return m_buffer; }
|
const char* data() const { return m_buffer; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual i64 read_into(void* ptr, i64 length) override;
|
virtual size_t read_into(void* ptr, size_t length) override;
|
||||||
virtual i64 write_from(const void* ptr, i64 length) override;
|
virtual size_t write_from(const void* ptr, size_t length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* m_buffer;
|
char* m_buffer;
|
||||||
i64 m_capacity;
|
size_t m_capacity;
|
||||||
i64 m_length;
|
size_t m_length;
|
||||||
i64 m_position;
|
size_t m_position;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/streams/stream.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -11,22 +11,21 @@ namespace Blah
|
||||||
FileStream(const FilePath& path, FileMode mode);
|
FileStream(const FilePath& path, FileMode mode);
|
||||||
FileStream(FileStream&& fs) noexcept;
|
FileStream(FileStream&& fs) noexcept;
|
||||||
FileStream& operator=(FileStream&& fs) noexcept;
|
FileStream& operator=(FileStream&& fs) noexcept;
|
||||||
~FileStream();
|
|
||||||
|
|
||||||
i64 length() const override;
|
size_t length() const override;
|
||||||
i64 position() const override;
|
size_t position() const override;
|
||||||
i64 seek(i64 seekTo) override;
|
size_t seek(size_t position) override;
|
||||||
bool is_open() const override;
|
bool is_open() const override;
|
||||||
bool is_readable() const override;
|
bool is_readable() const override;
|
||||||
bool is_writable() const override;
|
bool is_writable() const override;
|
||||||
void close() override;
|
void close() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
i64 read_into(void* ptr, i64 length) override;
|
size_t read_into(void* ptr, size_t length) override;
|
||||||
i64 write_from(const void* ptr, i64 length) override;
|
size_t write_from(const void* ptr, size_t length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileMode m_mode;
|
FileMode m_mode;
|
||||||
void* m_handle;
|
FileRef m_file;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -7,14 +7,14 @@ namespace Blah
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemoryStream();
|
MemoryStream();
|
||||||
MemoryStream(char* data, i64 length);
|
MemoryStream(char* data, size_t length);
|
||||||
MemoryStream(MemoryStream&& ms) noexcept;
|
MemoryStream(MemoryStream&& ms) noexcept;
|
||||||
MemoryStream& operator=(MemoryStream&& ms) noexcept;
|
MemoryStream& operator=(MemoryStream&& ms) noexcept;
|
||||||
~MemoryStream() override { m_data = nullptr; m_length = m_position = 0; }
|
~MemoryStream() override { m_data = nullptr; m_length = m_position = 0; }
|
||||||
|
|
||||||
i64 length() const override { return m_length; }
|
size_t length() const override { return m_length; }
|
||||||
i64 position() const override { return m_position; }
|
size_t position() const override { return m_position; }
|
||||||
i64 seek(i64 seekTo) override { return m_position = (seekTo < 0 ? 0 : (seekTo > m_length ? m_length : seekTo)); }
|
size_t seek(size_t seekTo) override { return m_position = (seekTo < 0 ? 0 : (seekTo > m_length ? m_length : seekTo)); }
|
||||||
bool is_open() const override { return m_data != nullptr; }
|
bool is_open() const override { return m_data != nullptr; }
|
||||||
bool is_readable() const override { return true; }
|
bool is_readable() const override { return true; }
|
||||||
bool is_writable() const override { return true; }
|
bool is_writable() const override { return true; }
|
||||||
|
@ -24,12 +24,12 @@ namespace Blah
|
||||||
const char* data() const { return m_data; }
|
const char* data() const { return m_data; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
i64 read_into(void* ptr, i64 length) override;
|
size_t read_into(void* ptr, size_t length) override;
|
||||||
i64 write_from(const void* ptr, i64 length) override;
|
size_t write_from(const void* ptr, size_t length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* m_data;
|
char* m_data;
|
||||||
i64 m_length;
|
size_t m_length;
|
||||||
i64 m_position;
|
size_t m_position;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/containers/str.h>
|
#include <blah/containers/str.h>
|
||||||
#include <blah/streams/endian.h>
|
#include <blah/streams/endian.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -16,13 +16,13 @@ namespace Blah
|
||||||
virtual ~Stream() = default;
|
virtual ~Stream() = default;
|
||||||
|
|
||||||
// returns the length of the stream
|
// returns the length of the stream
|
||||||
virtual i64 length() const = 0;
|
virtual size_t length() const = 0;
|
||||||
|
|
||||||
// returns the position of the stream
|
// returns the position of the stream
|
||||||
virtual i64 position() const = 0;
|
virtual size_t position() const = 0;
|
||||||
|
|
||||||
// seeks the position of the stream
|
// seeks the position of the stream
|
||||||
virtual i64 seek(i64 seek_to) = 0;
|
virtual size_t seek(size_t position) = 0;
|
||||||
|
|
||||||
// returns true of the stream is open
|
// returns true of the stream is open
|
||||||
virtual bool is_open() const = 0;
|
virtual bool is_open() const = 0;
|
||||||
|
@ -37,10 +37,10 @@ namespace Blah
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
// pipes the contents of this stream to another stream
|
// pipes the contents of this stream to another stream
|
||||||
i64 pipe(Stream& to, i64 length);
|
size_t pipe(Stream& to, size_t length);
|
||||||
|
|
||||||
// reads the amount of bytes into the given buffer, and returns the amount read
|
// reads the amount of bytes into the given buffer, and returns the amount read
|
||||||
i64 read(void* buffer, i64 length) { return read_into(buffer, length); }
|
size_t read(void* buffer, size_t length) { return read_into(buffer, length); }
|
||||||
|
|
||||||
// reads a string. if length < 0, assumes null-terminated
|
// reads a string. if length < 0, assumes null-terminated
|
||||||
String read_string(int length = -1);
|
String read_string(int length = -1);
|
||||||
|
@ -67,21 +67,21 @@ namespace Blah
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes the amount of bytes to the stream from the given buffer, and returns the amount written
|
// writes the amount of bytes to the stream from the given buffer, and returns the amount written
|
||||||
i64 write(const void* buffer, i64 length);
|
size_t write(const void* buffer, size_t length);
|
||||||
|
|
||||||
// writes the contents of a string to the stream
|
// writes the contents of a string to the stream
|
||||||
i64 write(const String& string);
|
size_t write(const String& string);
|
||||||
|
|
||||||
// writes a number
|
// writes a number
|
||||||
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
|
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
|
||||||
i64 write(const T& value)
|
size_t write(const T& value)
|
||||||
{
|
{
|
||||||
return write<T>(value, Endian::Little);
|
return write<T>(value, Endian::Little);
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes a number
|
// writes a number
|
||||||
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
|
template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
|
||||||
i64 write(const T& value, Endian endian)
|
size_t write(const T& value, Endian endian)
|
||||||
{
|
{
|
||||||
T writing = value;
|
T writing = value;
|
||||||
|
|
||||||
|
@ -93,9 +93,9 @@ namespace Blah
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// reads from the stream into the given buffer, and returns the number of bytes read
|
// reads from the stream into the given buffer, and returns the number of bytes read
|
||||||
virtual i64 read_into(void* buffer, i64 length) = 0;
|
virtual size_t read_into(void* buffer, size_t length) = 0;
|
||||||
|
|
||||||
// writes from the stream from the given buffer, and returns the number of bytes written
|
// writes from the stream from the given buffer, and returns the number of bytes written
|
||||||
virtual i64 write_from(const void* buffer, i64 length) = 0;
|
virtual size_t write_from(const void* buffer, size_t length) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -47,4 +47,16 @@ namespace Blah
|
||||||
// returns true between time intervals
|
// returns true between time intervals
|
||||||
static bool between_interval(float interval, float offset = 0);
|
static bool between_interval(float interval, float offset = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Stopwatch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Stopwatch();
|
||||||
|
void reset();
|
||||||
|
u64 microseconds();
|
||||||
|
u64 milliseconds();
|
||||||
|
|
||||||
|
private:
|
||||||
|
u64 start_time;
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
#include <blah/core/app.h>
|
#include <blah/app.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/core/time.h>
|
#include <blah/time.h>
|
||||||
#include <blah/math/point.h>
|
#include <blah/numerics/point.h>
|
||||||
#include <blah/graphics/framebuffer.h>
|
#include <blah/graphics/target.h>
|
||||||
#include "../internal/platform_backend.h"
|
#include "internal/platform_backend.h"
|
||||||
#include "../internal/graphics_backend.h"
|
#include "internal/graphics_backend.h"
|
||||||
#include "../internal/input_backend.h"
|
#include "internal/input_backend.h"
|
||||||
|
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
#include <emscripten.h>
|
#include <emscripten.h>
|
||||||
|
@ -261,21 +261,20 @@ namespace
|
||||||
{
|
{
|
||||||
// A dummy Frame Buffer that represents the Back Buffer
|
// A dummy Frame Buffer that represents the Back Buffer
|
||||||
// it doesn't actually contain any textures or details.
|
// it doesn't actually contain any textures or details.
|
||||||
class BackBuffer final : public FrameBuffer
|
class BackBuffer final : public Target
|
||||||
{
|
{
|
||||||
Attachments empty_attachments;
|
Attachments empty_textures;
|
||||||
TextureRef empty_texture;
|
|
||||||
|
|
||||||
Attachments& attachments() override
|
Attachments& textures() override
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(false, "Backbuffer doesn't have any attachments");
|
BLAH_ASSERT(false, "Backbuffer doesn't have any textures");
|
||||||
return empty_attachments;
|
return empty_textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Attachments& attachments() const override
|
const Attachments& textures() const override
|
||||||
{
|
{
|
||||||
BLAH_ASSERT(false, "Backbuffer doesn't have any attachments");
|
BLAH_ASSERT(false, "Backbuffer doesn't have any textures");
|
||||||
return empty_attachments;
|
return empty_textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
int width() const override
|
int width() const override
|
||||||
|
@ -296,4 +295,4 @@ namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const FrameBufferRef App::backbuffer = FrameBufferRef(new BackBuffer());
|
extern const TargetRef App::backbuffer = TargetRef(new BackBuffer());
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/core/app.h>
|
#include <blah/app.h>
|
||||||
#include <stdarg.h> // for logging methods
|
#include <stdarg.h> // for logging methods
|
||||||
#include <stdio.h> // for sprintf
|
#include <stdio.h> // for sprintf
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
#include <blah/streams/filestream.h>
|
#include <blah/streams/filestream.h>
|
||||||
#include "../internal/platform_backend.h"
|
#include "internal/platform_backend.h"
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
FileRef File::open(const FilePath& path, FileMode mode)
|
||||||
|
{
|
||||||
|
return PlatformBackend::file_open(path.cstr(), mode);
|
||||||
|
}
|
||||||
|
|
||||||
bool File::exists(const FilePath& path)
|
bool File::exists(const FilePath& path)
|
||||||
{
|
{
|
||||||
return PlatformBackend::file_exists(path.cstr());
|
return PlatformBackend::file_exists(path.cstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool File::remove(const FilePath& path)
|
bool File::destroy(const FilePath& path)
|
||||||
{
|
{
|
||||||
return PlatformBackend::file_delete(path.cstr());
|
return PlatformBackend::file_delete(path.cstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream File::open(const FilePath& path , FileMode mode)
|
|
||||||
{
|
|
||||||
return FileStream(path, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Directory::create(const FilePath& path)
|
bool Directory::create(const FilePath& path)
|
||||||
{
|
{
|
||||||
return PlatformBackend::dir_create(path.cstr());
|
return PlatformBackend::dir_create(path.cstr());
|
||||||
|
@ -29,7 +29,7 @@ bool Directory::exists(const FilePath& path)
|
||||||
return PlatformBackend::dir_exists(path.cstr());
|
return PlatformBackend::dir_exists(path.cstr());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Directory::remove(const FilePath& path)
|
bool Directory::destroy(const FilePath& path)
|
||||||
{
|
{
|
||||||
return PlatformBackend::dir_delete(path.cstr());
|
return PlatformBackend::dir_delete(path.cstr());
|
||||||
}
|
}
|
||||||
|
@ -56,11 +56,11 @@ void Directory::explore(const FilePath& path)
|
||||||
FilePath Path::get_file_name(const FilePath& path)
|
FilePath Path::get_file_name(const FilePath& path)
|
||||||
{
|
{
|
||||||
const char* cstr = path.cstr();
|
const char* cstr = path.cstr();
|
||||||
for (int n = path.length() - 2; n >= 0; n --)
|
auto length = path.length();
|
||||||
if (*(cstr + n) == '/')
|
|
||||||
{
|
for (auto n = length; n > 0; n--)
|
||||||
return FilePath(cstr + n + 1);
|
if (*(cstr + n - 1) == '/')
|
||||||
}
|
return FilePath(cstr + n);
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ FilePath Path::get_directory_name(const FilePath& path)
|
||||||
FilePath directory = path;
|
FilePath directory = path;
|
||||||
while (directory.ends_with("/"))
|
while (directory.ends_with("/"))
|
||||||
directory = directory.substr(0, -1);
|
directory = directory.substr(0, -1);
|
||||||
int last = directory.last_index_of('/');
|
auto last = directory.last_index_of('/');
|
||||||
if (last >= 0)
|
if (last >= 0)
|
||||||
directory = directory.substr(0, last + 1);
|
directory = directory.substr(0, last + 1);
|
||||||
return directory;
|
return directory;
|
||||||
|
@ -107,8 +107,8 @@ FilePath Path::normalize(const FilePath& path)
|
||||||
{
|
{
|
||||||
FilePath normalized;
|
FilePath normalized;
|
||||||
|
|
||||||
int len = path.length();
|
auto len = path.length();
|
||||||
for (int n = 0; n < len; n++)
|
for (auto n = 0; n < len; n++)
|
||||||
{
|
{
|
||||||
// normalize slashes
|
// normalize slashes
|
||||||
if (path[n] == '\\' || path[n] == '/')
|
if (path[n] == '\\' || path[n] == '/')
|
||||||
|
@ -120,16 +120,19 @@ FilePath Path::normalize(const FilePath& path)
|
||||||
else if (path[n] == '.' && n < len - 1 && path[n + 1] == '.')
|
else if (path[n] == '.' && n < len - 1 && path[n + 1] == '.')
|
||||||
{
|
{
|
||||||
// search backwards for last /
|
// search backwards for last /
|
||||||
bool couldMoveUp = false;
|
bool could_move_up = false;
|
||||||
for (int k = normalized.length() - 2; k >= 0; k--)
|
if (normalized.length() > 0)
|
||||||
if (normalized[k] == '/')
|
{
|
||||||
{
|
for (auto k = normalized.length() - 1; k > 0; k--)
|
||||||
normalized = normalized.substr(0, k);
|
if (normalized[k - 1] == '/')
|
||||||
couldMoveUp = true;
|
{
|
||||||
break;
|
normalized = normalized.substr(0, k - 1);
|
||||||
}
|
could_move_up = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!couldMoveUp)
|
if (!could_move_up)
|
||||||
normalized.append('.');
|
normalized.append('.');
|
||||||
else
|
else
|
||||||
n++;
|
n++;
|
|
@ -1,11 +1,11 @@
|
||||||
#include <blah/graphics/batch.h>
|
#include <blah/graphics/batch.h>
|
||||||
#include <blah/graphics/texture.h>
|
#include <blah/graphics/texture.h>
|
||||||
#include <blah/graphics/framebuffer.h>
|
#include <blah/graphics/target.h>
|
||||||
#include <blah/graphics/mesh.h>
|
#include <blah/graphics/mesh.h>
|
||||||
#include <blah/graphics/shader.h>
|
#include <blah/graphics/shader.h>
|
||||||
#include <blah/graphics/material.h>
|
#include <blah/graphics/material.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
#include <blah/core/app.h>
|
#include <blah/app.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
@ -185,7 +185,7 @@ namespace
|
||||||
#define INSERT_BATCH() \
|
#define INSERT_BATCH() \
|
||||||
do { \
|
do { \
|
||||||
m_batches.expand(); \
|
m_batches.expand(); \
|
||||||
for (int i = m_batches.size() - 1; i > m_batch_insert; i --) \
|
for (auto i = m_batches.size() - 1; i > m_batch_insert; i --) \
|
||||||
m_batches[i] = std::move(m_batches[i - 1]); \
|
m_batches[i] = std::move(m_batches[i - 1]); \
|
||||||
m_batches[m_batch_insert++] = m_batch; \
|
m_batches[m_batch_insert++] = m_batch; \
|
||||||
m_batch.offset += m_batch.elements; \
|
m_batch.offset += m_batch.elements; \
|
||||||
|
@ -378,7 +378,7 @@ void Batch::set_sampler(const TextureSampler& sampler)
|
||||||
m_batch.sampler = sampler;
|
m_batch.sampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::render(const FrameBufferRef& target)
|
void Batch::render(const TargetRef& target)
|
||||||
{
|
{
|
||||||
Point size;
|
Point size;
|
||||||
if (!target)
|
if (!target)
|
||||||
|
@ -389,7 +389,7 @@ void Batch::render(const FrameBufferRef& target)
|
||||||
render(target, Mat4x4::create_ortho_offcenter(0, (float)size.x, (float)size.y, 0, 0.01f, 1000.0f));
|
render(target, Mat4x4::create_ortho_offcenter(0, (float)size.x, (float)size.y, 0, 0.01f, 1000.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch::render(const FrameBufferRef& target, const Mat4x4& matrix)
|
void Batch::render(const TargetRef& target, const Mat4x4& matrix)
|
||||||
{
|
{
|
||||||
// nothing to draw
|
// nothing to draw
|
||||||
if ((m_batches.size() <= 0 && m_batch.elements <= 0) || m_indices.size() <= 0)
|
if ((m_batches.size() <= 0 && m_batch.elements <= 0) || m_indices.size() <= 0)
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
#include <blah/graphics/framebuffer.h>
|
|
||||||
#include "../internal/graphics_backend.h"
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
FrameBufferRef FrameBuffer::create(int width, int height)
|
|
||||||
{
|
|
||||||
return create(width, height, { TextureFormat::RGBA });
|
|
||||||
}
|
|
||||||
|
|
||||||
FrameBufferRef FrameBuffer::create(int width, int height, const AttachmentFormats& attachments)
|
|
||||||
{
|
|
||||||
BLAH_ASSERT(width > 0 && height > 0, "FrameBuffer width and height must be larger than 0");
|
|
||||||
BLAH_ASSERT(attachments.size() > 0, "At least one attachment must be provided");
|
|
||||||
|
|
||||||
int color_count = 0;
|
|
||||||
int depth_count = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < attachments.size(); i++)
|
|
||||||
{
|
|
||||||
BLAH_ASSERT((int)attachments[i] > (int)TextureFormat::None && (int)attachments[i] < (int)TextureFormat::Count, "Invalid texture format");
|
|
||||||
|
|
||||||
if (attachments[i] == TextureFormat::DepthStencil)
|
|
||||||
depth_count++;
|
|
||||||
else
|
|
||||||
color_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
BLAH_ASSERT(depth_count <= 1, "FrameBuffer can only have 1 Depth/Stencil Texture");
|
|
||||||
BLAH_ASSERT(color_count <= Attachments::MaxCapacity - 1, "Exceeded maximum Color attachment count");
|
|
||||||
|
|
||||||
return GraphicsBackend::create_framebuffer(width, height, attachments.data(), attachments.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureRef& FrameBuffer::attachment(int index)
|
|
||||||
{
|
|
||||||
return attachments()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
const TextureRef& FrameBuffer::attachment(int index) const
|
|
||||||
{
|
|
||||||
return attachments()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
int FrameBuffer::width() const
|
|
||||||
{
|
|
||||||
return attachments()[0]->width();
|
|
||||||
}
|
|
||||||
|
|
||||||
int FrameBuffer::height() const
|
|
||||||
{
|
|
||||||
return attachments()[0]->height();
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/graphics/material.h>
|
#include <blah/graphics/material.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
@ -19,7 +19,7 @@ namespace
|
||||||
case UniformType::Mat3x2: components = 6; break;
|
case UniformType::Mat3x2: components = 6; break;
|
||||||
case UniformType::Mat4x4: components = 16; break;
|
case UniformType::Mat4x4: components = 16; break;
|
||||||
default:
|
default:
|
||||||
BLAH_ERROR("Unespected Uniform Type");
|
BLAH_ASSERT(false, "Unespected Uniform Type");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/graphics/renderpass.h>
|
#include <blah/graphics/renderpass.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include "../internal/graphics_backend.h"
|
#include "../internal/graphics_backend.h"
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
@ -66,11 +66,7 @@ void RenderPass::perform()
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the total drawable size
|
// get the total drawable size
|
||||||
Vec2 draw_size;
|
auto draw_size = Vec2(pass.target->width(), pass.target->height());
|
||||||
if (!pass.target)
|
|
||||||
draw_size = Vec2(App::draw_width(), App::draw_height());
|
|
||||||
else
|
|
||||||
draw_size = Vec2(pass.target->width(), pass.target->height());
|
|
||||||
|
|
||||||
// Validate Viewport
|
// Validate Viewport
|
||||||
if (!pass.has_viewport)
|
if (!pass.has_viewport)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/graphics/shader.h>
|
#include <blah/graphics/shader.h>
|
||||||
#include <blah/core/app.h>
|
#include <blah/app.h>
|
||||||
#include "../internal/graphics_backend.h"
|
#include "../internal/graphics_backend.h"
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
@ -21,7 +21,8 @@ ShaderRef Shader::create(const ShaderData& data)
|
||||||
for (auto& it : uniforms)
|
for (auto& it : uniforms)
|
||||||
if (it.type == UniformType::None)
|
if (it.type == UniformType::None)
|
||||||
{
|
{
|
||||||
BLAH_ERROR_FMT("Uniform '%s' has an invalid type!\n\tOnly Float/Float2/Float3/Float4/Mat3x2/Mat4x4/Texture are allowed!", it.name.cstr());
|
auto error = String::fmt("Uniform '%s' has an invalid type!\n\tOnly Float/Float2/Float3/Float4/Mat3x2/Mat4x4/Texture are allowed!", it.name.cstr());
|
||||||
|
BLAH_ASSERT(false, error.cstr());
|
||||||
return ShaderRef();
|
return ShaderRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +31,8 @@ ShaderRef Shader::create(const ShaderData& data)
|
||||||
for (int j = i + 1; j < uniforms.size(); j ++)
|
for (int j = i + 1; j < uniforms.size(); j ++)
|
||||||
if (uniforms[i].name == uniforms[j].name)
|
if (uniforms[i].name == uniforms[j].name)
|
||||||
{
|
{
|
||||||
BLAH_ERROR_FMT("Shader Uniform names '%s' overlap! All Names must be unique.", uniforms[0].name.cstr());
|
auto error = String::fmt("Shader Uniform names '%s' overlap! All Names must be unique.", uniforms[0].name.cstr());
|
||||||
|
BLAH_ASSERT(false, error.cstr());
|
||||||
return ShaderRef();
|
return ShaderRef();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <blah/graphics/spritefont.h>
|
#include <blah/graphics/spritefont.h>
|
||||||
#include <blah/images/font.h>
|
#include <blah/images/font.h>
|
||||||
#include <blah/images/packer.h>
|
#include <blah/images/packer.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ float SpriteFont::width_of_line(const String& text, int start) const
|
||||||
float width = 0;
|
float width = 0;
|
||||||
|
|
||||||
Codepoint last = 0;
|
Codepoint last = 0;
|
||||||
for (int i = start; i < text.length(); i ++)
|
for (auto i = start; i < text.length(); i ++)
|
||||||
{
|
{
|
||||||
if (text[i] == '\n')
|
if (text[i] == '\n')
|
||||||
return width;
|
return width;
|
||||||
|
@ -139,7 +139,9 @@ float SpriteFont::width_of_line(const String& text, int start) const
|
||||||
width += get_kerning(last, next);
|
width += get_kerning(last, next);
|
||||||
|
|
||||||
// move to thext utf8 character
|
// move to thext utf8 character
|
||||||
i += text.utf8_length(i) - 1;
|
auto len = text.utf8_length(i);
|
||||||
|
if (len > 0)
|
||||||
|
i += len - 1;
|
||||||
|
|
||||||
last = next;
|
last = next;
|
||||||
}
|
}
|
||||||
|
@ -153,7 +155,7 @@ float SpriteFont::height_of(const String& text) const
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
float height = line_height();
|
float height = line_height();
|
||||||
for (int i = 0; i < text.length(); i ++)
|
for (auto i = 0; i < text.length(); i ++)
|
||||||
{
|
{
|
||||||
if (text[i] == '\n')
|
if (text[i] == '\n')
|
||||||
height += line_height();
|
height += line_height();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/graphics/subtexture.h>
|
#include <blah/graphics/subtexture.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
|
53
src/graphics/target.cpp
Normal file
53
src/graphics/target.cpp
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#include <blah/graphics/target.h>
|
||||||
|
#include "../internal/graphics_backend.h"
|
||||||
|
|
||||||
|
using namespace Blah;
|
||||||
|
|
||||||
|
TargetRef Target::create(int width, int height)
|
||||||
|
{
|
||||||
|
return create(width, height, { TextureFormat::RGBA });
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetRef Target::create(int width, int height, const AttachmentFormats& textures)
|
||||||
|
{
|
||||||
|
BLAH_ASSERT(width > 0 && height > 0, "Target width and height must be larger than 0");
|
||||||
|
BLAH_ASSERT(textures.size() > 0, "At least one texture must be provided");
|
||||||
|
|
||||||
|
int color_count = 0;
|
||||||
|
int depth_count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < textures.size(); i++)
|
||||||
|
{
|
||||||
|
BLAH_ASSERT((int)textures[i] > (int)TextureFormat::None && (int)textures[i] < (int)TextureFormat::Count, "Invalid texture format");
|
||||||
|
|
||||||
|
if (textures[i] == TextureFormat::DepthStencil)
|
||||||
|
depth_count++;
|
||||||
|
else
|
||||||
|
color_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
BLAH_ASSERT(depth_count <= 1, "Target can only have 1 Depth/Stencil Texture");
|
||||||
|
BLAH_ASSERT(color_count <= Attachments::capacity - 1, "Exceeded maximum Color texture count");
|
||||||
|
|
||||||
|
return GraphicsBackend::create_target(width, height, textures.data(), textures.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureRef& Target::texture(int index)
|
||||||
|
{
|
||||||
|
return textures()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const TextureRef& Target::texture(int index) const
|
||||||
|
{
|
||||||
|
return textures()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
int Target::width() const
|
||||||
|
{
|
||||||
|
return textures()[0]->width();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Target::height() const
|
||||||
|
{
|
||||||
|
return textures()[0]->height();
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#include <blah/graphics/texture.h>
|
#include <blah/graphics/texture.h>
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/streams/stream.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include "../internal/graphics_backend.h"
|
#include "../internal/graphics_backend.h"
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include <blah/images/aseprite.h>
|
#include <blah/images/aseprite.h>
|
||||||
#include <blah/streams/filestream.h>
|
#include <blah/streams/filestream.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
|
|
||||||
#define STBI_NO_STDIO
|
#define STBI_NO_STDIO
|
||||||
#define STBI_ONLY_ZLIB
|
#define STBI_ONLY_ZLIB
|
||||||
|
@ -81,7 +81,7 @@ void Aseprite::parse(Stream& stream)
|
||||||
{
|
{
|
||||||
if (!stream.is_readable())
|
if (!stream.is_readable())
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Stream is not readable");
|
BLAH_ASSERT(false, "Stream is not readable");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ void Aseprite::parse(Stream& stream)
|
||||||
auto magic = stream.read<u16>(Endian::Little);
|
auto magic = stream.read<u16>(Endian::Little);
|
||||||
if (magic != 0xA5E0)
|
if (magic != 0xA5E0)
|
||||||
{
|
{
|
||||||
BLAH_ERROR("File is not a valid Aseprite file");
|
BLAH_ASSERT(false, "File is not a valid Aseprite file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ void Aseprite::parse(Stream& stream)
|
||||||
auto magic = stream.read<u16>(Endian::Little); // magic number
|
auto magic = stream.read<u16>(Endian::Little); // magic number
|
||||||
if (magic != 0xF1FA)
|
if (magic != 0xF1FA)
|
||||||
{
|
{
|
||||||
BLAH_ERROR("File is not a valid Aseprite file");
|
BLAH_ASSERT(false, "File is not a valid Aseprite file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ void Aseprite::parse_cel(Stream& stream, int frameIndex, size_t maxPosition)
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Unable to parse Aseprite file");
|
BLAH_ASSERT(false, "Unable to parse Aseprite file");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,6 +460,6 @@ void Aseprite::render_cel(Cel* cel, Frame* frame)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Aseprite blendmodes aren't implemented");
|
BLAH_ASSERT(false, "Aseprite blendmodes aren't implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <blah/images/font.h>
|
#include <blah/images/font.h>
|
||||||
#include <blah/streams/filestream.h>
|
#include <blah/streams/filestream.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ void Font::load(Stream& stream)
|
||||||
|
|
||||||
if (!stream.is_readable())
|
if (!stream.is_readable())
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Unable to load a font as the Stream was not readable");
|
BLAH_ASSERT(false, "Unable to load a font as the Stream was not readable");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <blah/images/image.h>
|
#include <blah/images/image.h>
|
||||||
#include <blah/streams/stream.h>
|
#include <blah/streams/stream.h>
|
||||||
#include <blah/streams/filestream.h>
|
#include <blah/streams/filestream.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ void Image::from_stream(Stream& stream)
|
||||||
|
|
||||||
if (!stream.is_readable())
|
if (!stream.is_readable())
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Unable to load image as the Stream was not readable");
|
BLAH_ASSERT(false, "Unable to load image as the Stream was not readable");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ void Image::from_stream(Stream& stream)
|
||||||
|
|
||||||
if (data == nullptr)
|
if (data == nullptr)
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Unable to load image as the Stream's data was not a valid image");
|
BLAH_ASSERT(false, "Unable to load image as the Stream's data was not a valid image");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/images/packer.h>
|
#include <blah/images/packer.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ void Packer::pack()
|
||||||
// make sure the largest isn't too large
|
// make sure the largest isn't too large
|
||||||
if (sources[0]->packed.w + padding * 2 > max_size || sources[0]->packed.h + padding * 2 > max_size)
|
if (sources[0]->packed.w + padding * 2 > max_size || sources[0]->packed.h + padding * 2 > max_size)
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Source image is larger than max atlas size");
|
BLAH_ASSERT(false, "Source image is larger than max atlas size");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
937
src/input.cpp
Normal file
937
src/input.cpp
Normal file
|
@ -0,0 +1,937 @@
|
||||||
|
#include <blah/input.h>
|
||||||
|
#include <blah/app.h>
|
||||||
|
#include <blah/time.h>
|
||||||
|
#include <blah/common.h>
|
||||||
|
#include <blah/numerics/point.h>
|
||||||
|
#include <blah/numerics/calc.h>
|
||||||
|
#include "internal/input_backend.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace Blah;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
InputState g_last_state;
|
||||||
|
InputState g_curr_state;
|
||||||
|
InputState g_next_state;
|
||||||
|
InputState g_empty_state;
|
||||||
|
ControllerState g_empty_controller;
|
||||||
|
Vector<WeakRef<InputBinding>> g_bindings;
|
||||||
|
Vector<WeakRef<AxisBinding>> g_axes;
|
||||||
|
Vector<WeakRef<StickBinding>> g_sticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::init()
|
||||||
|
{
|
||||||
|
g_empty_controller.name = "Disconnected";
|
||||||
|
for (int i = 0; i < Blah::Input::max_controllers; i++)
|
||||||
|
g_empty_state.controllers[i].name = g_empty_controller.name;
|
||||||
|
|
||||||
|
g_last_state = g_empty_state;
|
||||||
|
g_curr_state = g_empty_state;
|
||||||
|
g_next_state = g_empty_state;
|
||||||
|
g_bindings.dispose();
|
||||||
|
g_axes.dispose();
|
||||||
|
g_sticks.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::frame()
|
||||||
|
{
|
||||||
|
// cycle states
|
||||||
|
g_last_state = g_curr_state;
|
||||||
|
g_curr_state = g_next_state;
|
||||||
|
|
||||||
|
// copy state, clear pressed / released values
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Blah::Input::max_keyboard_keys; i++)
|
||||||
|
{
|
||||||
|
g_next_state.keyboard.pressed[i] = false;
|
||||||
|
g_next_state.keyboard.released[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Blah::Input::max_mouse_buttons; i++)
|
||||||
|
{
|
||||||
|
g_next_state.mouse.pressed[i] = false;
|
||||||
|
g_next_state.mouse.released[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_next_state.mouse.wheel = Point::zero;
|
||||||
|
g_next_state.keyboard.text.clear();
|
||||||
|
|
||||||
|
for (int i = 0; i < Blah::Input::max_controllers; i++)
|
||||||
|
{
|
||||||
|
ControllerState* controller = &(g_next_state.controllers[i]);
|
||||||
|
|
||||||
|
if (!controller->is_connected)
|
||||||
|
controller->name = nullptr;
|
||||||
|
|
||||||
|
for (int j = 0; j < Blah::Input::max_controller_buttons; j++)
|
||||||
|
{
|
||||||
|
controller->pressed[j] = false;
|
||||||
|
controller->released[j] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update bindings
|
||||||
|
|
||||||
|
for (int i = 0; i < g_bindings.size(); i++)
|
||||||
|
{
|
||||||
|
if (g_bindings[i].use_count() <= 0)
|
||||||
|
{
|
||||||
|
g_bindings.erase(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else if (auto binding = g_bindings[i].lock())
|
||||||
|
{
|
||||||
|
binding->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < g_axes.size(); i++)
|
||||||
|
{
|
||||||
|
if (g_axes[i].use_count() <= 0)
|
||||||
|
{
|
||||||
|
g_axes.erase(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else if (auto binding = g_axes[i].lock())
|
||||||
|
{
|
||||||
|
binding->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < g_sticks.size(); i++)
|
||||||
|
{
|
||||||
|
if (g_sticks[i].use_count() <= 0)
|
||||||
|
{
|
||||||
|
g_sticks.erase(i);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else if (auto binding = g_sticks[i].lock())
|
||||||
|
{
|
||||||
|
binding->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_mouse_move(float x, float y)
|
||||||
|
{
|
||||||
|
g_next_state.mouse.position.x = x;
|
||||||
|
g_next_state.mouse.position.y = y;
|
||||||
|
|
||||||
|
Point size = Point(App::width(), App::height());
|
||||||
|
Point draw = Point(App::draw_width(), App::draw_height());
|
||||||
|
|
||||||
|
g_next_state.mouse.draw_position.x = (x / (float)size.x) * draw.x;
|
||||||
|
g_next_state.mouse.draw_position.y = (y / (float)size.y) * draw.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_mouse_screen_move(float x, float y)
|
||||||
|
{
|
||||||
|
g_next_state.mouse.screen_position.x = x;
|
||||||
|
g_next_state.mouse.screen_position.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_mouse_down(MouseButton button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
if (i >= 0 && i < Blah::Input::max_mouse_buttons)
|
||||||
|
{
|
||||||
|
g_next_state.mouse.down[i] = true;
|
||||||
|
g_next_state.mouse.pressed[i] = true;
|
||||||
|
g_next_state.mouse.timestamp[i] = Time::ticks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_mouse_up(MouseButton button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
if (i >= 0 && i < Blah::Input::max_mouse_buttons)
|
||||||
|
{
|
||||||
|
g_next_state.mouse.down[i] = false;
|
||||||
|
g_next_state.mouse.released[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_key_down(Key key)
|
||||||
|
{
|
||||||
|
int i = (int)key;
|
||||||
|
if (i >= 0 && i < Blah::Input::max_keyboard_keys)
|
||||||
|
{
|
||||||
|
g_next_state.keyboard.down[i] = true;
|
||||||
|
g_next_state.keyboard.pressed[i] = true;
|
||||||
|
g_next_state.keyboard.timestamp[i] = Time::ticks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_mouse_wheel(Point wheel)
|
||||||
|
{
|
||||||
|
g_next_state.mouse.wheel = wheel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_key_up(Key key)
|
||||||
|
{
|
||||||
|
int i = (int)key;
|
||||||
|
if (i >= 0 && i < Blah::Input::max_keyboard_keys)
|
||||||
|
{
|
||||||
|
g_next_state.keyboard.down[i] = false;
|
||||||
|
g_next_state.keyboard.released[i] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_text_utf8(const char* text)
|
||||||
|
{
|
||||||
|
g_next_state.keyboard.text += text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_controller_connect(int index, const char* name, int is_gamepad, int button_count, int axis_count, u16 vendor, u16 product, u16 version)
|
||||||
|
{
|
||||||
|
if (index < Blah::Input::max_controllers)
|
||||||
|
{
|
||||||
|
ControllerState* controller = &(g_next_state.controllers[index]);
|
||||||
|
*controller = g_empty_controller;
|
||||||
|
controller->name = name;
|
||||||
|
controller->is_connected = true;
|
||||||
|
controller->is_gamepad = is_gamepad;
|
||||||
|
controller->button_count = button_count;
|
||||||
|
controller->axis_count = axis_count;
|
||||||
|
controller->vendor = vendor;
|
||||||
|
controller->product = product;
|
||||||
|
controller->version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_controller_disconnect(int index)
|
||||||
|
{
|
||||||
|
if (index < Blah::Input::max_controllers)
|
||||||
|
g_next_state.controllers[index] = g_empty_controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_button_down(int index, int button)
|
||||||
|
{
|
||||||
|
if (index < Blah::Input::max_controllers &&
|
||||||
|
button < Blah::Input::max_controller_buttons &&
|
||||||
|
g_next_state.controllers[index].is_connected &&
|
||||||
|
button < g_next_state.controllers[index].button_count)
|
||||||
|
{
|
||||||
|
g_next_state.controllers[index].down[button] = true;
|
||||||
|
g_next_state.controllers[index].pressed[button] = true;
|
||||||
|
g_next_state.controllers[index].button_timestamp[button] = Time::ticks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_button_up(int index, int button)
|
||||||
|
{
|
||||||
|
if (index < Blah::Input::max_controllers &&
|
||||||
|
button < Blah::Input::max_controller_buttons &&
|
||||||
|
g_next_state.controllers[index].is_connected &&
|
||||||
|
button < g_next_state.controllers[index].button_count)
|
||||||
|
{
|
||||||
|
g_next_state.controllers[index].down[button] = false;
|
||||||
|
g_next_state.controllers[index].released[button] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBackend::on_axis_move(int index, int axis, float value)
|
||||||
|
{
|
||||||
|
if (index < Blah::Input::max_controllers &&
|
||||||
|
axis < Blah::Input::max_controller_axis &&
|
||||||
|
g_next_state.controllers[index].is_connected &&
|
||||||
|
axis < g_next_state.controllers[index].axis_count)
|
||||||
|
{
|
||||||
|
g_next_state.controllers[index].axis[axis] = value;
|
||||||
|
g_next_state.controllers[index].axis_timestamp[axis] = Time::ticks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const InputState* Input::state()
|
||||||
|
{
|
||||||
|
return &g_curr_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InputState* Input::last_state()
|
||||||
|
{
|
||||||
|
return &g_last_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2 Input::mouse()
|
||||||
|
{
|
||||||
|
return g_curr_state.mouse.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Vec2 Input::mouse_draw()
|
||||||
|
{
|
||||||
|
return Vec2(g_curr_state.mouse.draw_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2 Input::mouse_screen()
|
||||||
|
{
|
||||||
|
return Vec2(g_curr_state.mouse.screen_position);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::pressed(MouseButton button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.pressed[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::down(MouseButton button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.down[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::released(MouseButton button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.released[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
Point Input::mouse_wheel()
|
||||||
|
{
|
||||||
|
return g_curr_state.mouse.wheel;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::pressed(Key key)
|
||||||
|
{
|
||||||
|
int i = (int)key;
|
||||||
|
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.pressed[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::down(Key key)
|
||||||
|
{
|
||||||
|
int i = (int)key;
|
||||||
|
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.down[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::released(Key key)
|
||||||
|
{
|
||||||
|
int i = (int)key;
|
||||||
|
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.released[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::ctrl()
|
||||||
|
{
|
||||||
|
return down(Key::LeftControl) || down(Key::RightControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::shift()
|
||||||
|
{
|
||||||
|
return down(Key::LeftShift) || down(Key::RightShift);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::alt()
|
||||||
|
{
|
||||||
|
return down(Key::LeftAlt) || down(Key::RightAlt);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Input::text()
|
||||||
|
{
|
||||||
|
return g_curr_state.keyboard.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ControllerState* Input::controller(int controllerIndex)
|
||||||
|
{
|
||||||
|
if (controllerIndex >= Blah::Input::max_controllers)
|
||||||
|
{
|
||||||
|
Log::warn("Trying to access a out-of-range controller at %i", controllerIndex);
|
||||||
|
return &g_empty_controller;
|
||||||
|
}
|
||||||
|
else if (!g_curr_state.controllers[controllerIndex].is_connected)
|
||||||
|
{
|
||||||
|
return &g_empty_controller;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return &g_curr_state.controllers[controllerIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::pressed(int controllerIndex, Button button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
|
||||||
|
return g_curr_state.controllers[controllerIndex].pressed[i];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::down(int controllerIndex, Button button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
|
||||||
|
return g_curr_state.controllers[controllerIndex].down[i];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Input::released(int controllerIndex, Button button)
|
||||||
|
{
|
||||||
|
int i = (int)button;
|
||||||
|
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
|
||||||
|
return g_curr_state.controllers[controllerIndex].released[i];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Input::axis_check(int controllerIndex, Axis axis)
|
||||||
|
{
|
||||||
|
int i = (int)axis;
|
||||||
|
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_axis)
|
||||||
|
return g_curr_state.controllers[controllerIndex].axis[i];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Input::axis_check(int fallback, Key negative, Key positive)
|
||||||
|
{
|
||||||
|
if (Input::pressed(positive))
|
||||||
|
return 1;
|
||||||
|
else if (Input::pressed(negative))
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool pos = Input::down(positive);
|
||||||
|
bool neg = Input::down(negative);
|
||||||
|
|
||||||
|
if (pos && neg)
|
||||||
|
return fallback;
|
||||||
|
else if (pos)
|
||||||
|
return 1;
|
||||||
|
else if (neg)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Input::axis_check(int fallback, int controllerIndex, Button negative, Button positive)
|
||||||
|
{
|
||||||
|
if (Input::pressed(controllerIndex, positive))
|
||||||
|
return 1;
|
||||||
|
else if (Input::pressed(controllerIndex, negative))
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool pos = Input::down(controllerIndex, positive);
|
||||||
|
bool neg = Input::down(controllerIndex, negative);
|
||||||
|
|
||||||
|
if (pos && neg)
|
||||||
|
return fallback;
|
||||||
|
else if (pos)
|
||||||
|
return 1;
|
||||||
|
else if (neg)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Input::name_of(Key key)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
#define DEFINE_KEY(name, value) case Key::name: return #name;
|
||||||
|
BLAH_KEY_DEFINITIONS
|
||||||
|
#undef DEFINE_KEY
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Input::name_of(Button button)
|
||||||
|
{
|
||||||
|
switch (button)
|
||||||
|
{
|
||||||
|
#define DEFINE_BTN(name, value) case Button::name: return #name;
|
||||||
|
BLAH_BUTTON_DEFINITIONS
|
||||||
|
#undef DEFINE_BTN
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBindingRef Input::register_binding(const InputBinding& binding)
|
||||||
|
{
|
||||||
|
auto result = std::make_shared<InputBinding>(binding);
|
||||||
|
g_bindings.push_back(WeakRef<InputBinding>(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
AxisBindingRef Input::register_binding(const AxisBinding& binding)
|
||||||
|
{
|
||||||
|
auto result = std::make_shared<AxisBinding>(binding);
|
||||||
|
g_axes.push_back(WeakRef<AxisBinding>(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
StickBindingRef Input::register_binding(const StickBinding& binding)
|
||||||
|
{
|
||||||
|
auto result = std::make_shared<StickBinding>(binding);
|
||||||
|
g_sticks.push_back(WeakRef<StickBinding>(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InputBinding::TriggerBind::TriggerBind(Axis axis)
|
||||||
|
: axis(axis)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding::TriggerBind::TriggerBind(int controller, Axis axis, float threshold, bool positive)
|
||||||
|
: controller(controller), axis(axis), threshold(threshold), positive(positive)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputBinding::TriggerBind::is_down(float axis_value) const
|
||||||
|
{
|
||||||
|
if ((axis_value > 0 && positive) || (axis_value < 0 && !positive))
|
||||||
|
{
|
||||||
|
if (Calc::abs(axis_value) >= threshold)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding::ButtonBind::ButtonBind(Button button)
|
||||||
|
: button(button) {}
|
||||||
|
|
||||||
|
InputBinding::ButtonBind::ButtonBind(int controller, Button button)
|
||||||
|
: controller(controller), button(button) {}
|
||||||
|
|
||||||
|
bool InputBinding::pressed() const
|
||||||
|
{
|
||||||
|
if (m_press_consumed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_last_press_time >= 0 && (Time::seconds - m_last_press_time) <= press_buffer)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return m_pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputBinding::released() const
|
||||||
|
{
|
||||||
|
if (m_release_consumed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_last_release_time >= 0 && (Time::seconds - m_last_release_time) <= release_buffer)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return m_released;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputBinding::down() const
|
||||||
|
{
|
||||||
|
return m_down;
|
||||||
|
}
|
||||||
|
|
||||||
|
float InputBinding::value() const
|
||||||
|
{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int InputBinding::sign() const
|
||||||
|
{
|
||||||
|
return (int)Calc::sign(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
double InputBinding::timestamp() const
|
||||||
|
{
|
||||||
|
return m_last_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBinding::update()
|
||||||
|
{
|
||||||
|
m_press_consumed = false;
|
||||||
|
m_release_consumed = false;
|
||||||
|
|
||||||
|
if (get_pressed())
|
||||||
|
{
|
||||||
|
m_last_timestamp = Time::seconds;
|
||||||
|
m_last_press_time = Time::seconds;
|
||||||
|
m_pressed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_pressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_released())
|
||||||
|
{
|
||||||
|
m_last_release_time = Time::seconds;
|
||||||
|
m_released = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_released = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_down = get_down();
|
||||||
|
m_value = get_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBinding::consume_press()
|
||||||
|
{
|
||||||
|
m_press_consumed = true;
|
||||||
|
m_last_press_time = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBinding::consume_release()
|
||||||
|
{
|
||||||
|
m_release_consumed = true;
|
||||||
|
m_last_release_time = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding& InputBinding::add(Key key)
|
||||||
|
{
|
||||||
|
keys.push_back(key);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding& InputBinding::add(ButtonBind button)
|
||||||
|
{
|
||||||
|
buttons.push_back(button);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding& InputBinding::add(TriggerBind trigger)
|
||||||
|
{
|
||||||
|
triggers.push_back(trigger);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding& InputBinding::add(MouseButton button)
|
||||||
|
{
|
||||||
|
mouse.push_back(button);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding& InputBinding::add_left_trigger(int controller, float threshold)
|
||||||
|
{
|
||||||
|
triggers.push_back(TriggerBind(controller, Axis::LeftTrigger, threshold, true));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding& InputBinding::add_right_trigger(int controller, float threshold)
|
||||||
|
{
|
||||||
|
triggers.push_back(TriggerBind(controller, Axis::RightTrigger, threshold, true));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputBinding& InputBinding::set_controller(int index)
|
||||||
|
{
|
||||||
|
for (auto& it : buttons)
|
||||||
|
it.controller = index;
|
||||||
|
for (auto& it : triggers)
|
||||||
|
it.controller = index;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputBinding::clear()
|
||||||
|
{
|
||||||
|
keys.clear();
|
||||||
|
buttons.clear();
|
||||||
|
triggers.clear();
|
||||||
|
mouse.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputBinding::get_pressed() const
|
||||||
|
{
|
||||||
|
for (auto& it : keys)
|
||||||
|
if (Input::pressed(it))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : mouse)
|
||||||
|
if (Input::pressed(it))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : buttons)
|
||||||
|
if (Input::pressed(it.controller, it.button))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : triggers)
|
||||||
|
{
|
||||||
|
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (it.is_down(Input::state()->controllers[it.controller].axis[(int)it.axis]) &&
|
||||||
|
!it.is_down(Input::last_state()->controllers[it.controller].axis[(int)it.axis]))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputBinding::get_released() const
|
||||||
|
{
|
||||||
|
for (auto& it : keys)
|
||||||
|
if (Input::released(it))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : mouse)
|
||||||
|
if (Input::released(it))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : buttons)
|
||||||
|
if (Input::released(it.controller, it.button))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : triggers)
|
||||||
|
{
|
||||||
|
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!it.is_down(Input::state()->controllers[it.controller].axis[(int)it.axis]) &&
|
||||||
|
it.is_down(Input::last_state()->controllers[it.controller].axis[(int)it.axis]))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputBinding::get_down() const
|
||||||
|
{
|
||||||
|
for (auto& it : keys)
|
||||||
|
if (Input::down(it))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : mouse)
|
||||||
|
if (Input::down(it))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : buttons)
|
||||||
|
if (Input::down(it.controller, it.button))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (auto& it : triggers)
|
||||||
|
{
|
||||||
|
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (it.is_down(Input::state()->controllers[it.controller].axis[(int)it.axis]))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
float InputBinding::get_value() const
|
||||||
|
{
|
||||||
|
for (auto& it : keys)
|
||||||
|
if (Input::down(it))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
for (auto& it : mouse)
|
||||||
|
if (Input::down(it))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
for (auto& it : buttons)
|
||||||
|
if (Input::down(it.controller, it.button))
|
||||||
|
return 1.0f;
|
||||||
|
|
||||||
|
float highest = 0;
|
||||||
|
|
||||||
|
for (auto& it : triggers)
|
||||||
|
{
|
||||||
|
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float raw_value = Input::state()->controllers[it.controller].axis[(int)it.axis];
|
||||||
|
|
||||||
|
if (it.is_down(raw_value))
|
||||||
|
{
|
||||||
|
float mapped_value = Calc::clamped_map(Calc::abs(raw_value), it.threshold, 1.0f, 0.0f, 1.0f);
|
||||||
|
if (mapped_value > highest)
|
||||||
|
highest = mapped_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return highest;
|
||||||
|
}
|
||||||
|
|
||||||
|
float AxisBinding::value() const
|
||||||
|
{
|
||||||
|
float neg = negative.value();
|
||||||
|
float pos = positive.value();
|
||||||
|
|
||||||
|
// neither are down
|
||||||
|
if (neg <= 0 && pos <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// negative-only is down
|
||||||
|
if (neg > 0 && pos <= 0)
|
||||||
|
return -neg;
|
||||||
|
|
||||||
|
// positive-only is down
|
||||||
|
if (pos > 0 && neg <= 0)
|
||||||
|
return pos;
|
||||||
|
|
||||||
|
// both are down:
|
||||||
|
|
||||||
|
// overlap cancel out
|
||||||
|
if (overlap == Overlap::Cancel)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// overlap takes older
|
||||||
|
if (overlap == Overlap::Older)
|
||||||
|
{
|
||||||
|
if (negative.timestamp() < positive.timestamp())
|
||||||
|
return -neg;
|
||||||
|
else
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overlap takes newer
|
||||||
|
if (negative.timestamp() > positive.timestamp())
|
||||||
|
return -neg;
|
||||||
|
else
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AxisBinding::sign() const
|
||||||
|
{
|
||||||
|
return (int)Calc::sign(value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxisBinding::update()
|
||||||
|
{
|
||||||
|
negative.update();
|
||||||
|
positive.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxisBinding::consume_press()
|
||||||
|
{
|
||||||
|
negative.consume_press();
|
||||||
|
positive.consume_press();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxisBinding::consume_release()
|
||||||
|
{
|
||||||
|
negative.consume_release();
|
||||||
|
positive.consume_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
AxisBinding& AxisBinding::add_left_stick_x(int controller, float threshold)
|
||||||
|
{
|
||||||
|
negative.add(InputBinding::TriggerBind(controller, Axis::LeftX, threshold, false));
|
||||||
|
positive.add(InputBinding::TriggerBind(controller, Axis::LeftX, threshold, true));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AxisBinding& AxisBinding::add_left_stick_y(int controller, float threshold)
|
||||||
|
{
|
||||||
|
negative.add(InputBinding::TriggerBind(controller, Axis::LeftY, threshold, false));
|
||||||
|
positive.add(InputBinding::TriggerBind(controller, Axis::LeftY, threshold, true));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AxisBinding& AxisBinding::add_right_stick_x(int controller, float threshold)
|
||||||
|
{
|
||||||
|
negative.add(InputBinding::TriggerBind(controller, Axis::RightX, threshold, false));
|
||||||
|
positive.add(InputBinding::TriggerBind(controller, Axis::RightX, threshold, true));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AxisBinding& AxisBinding::add_right_stick_y(int controller, float threshold)
|
||||||
|
{
|
||||||
|
negative.add(InputBinding::TriggerBind(controller, Axis::RightY, threshold, false));
|
||||||
|
positive.add(InputBinding::TriggerBind(controller, Axis::RightY, threshold, true));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
AxisBinding& AxisBinding::set_controller(int index)
|
||||||
|
{
|
||||||
|
negative.set_controller(index);
|
||||||
|
positive.set_controller(index);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxisBinding::clear()
|
||||||
|
{
|
||||||
|
negative.clear();
|
||||||
|
positive.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2 StickBinding::value() const
|
||||||
|
{
|
||||||
|
Vec2 result = Vec2(x.value(), y.value());
|
||||||
|
if (round_threshold > 0 && result.length() < round_threshold)
|
||||||
|
return Vec2::zero;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point StickBinding::sign() const
|
||||||
|
{
|
||||||
|
Vec2 result = value();
|
||||||
|
return Point((int)Calc::sign(result.x), (int)Calc::sign(result.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickBinding::update()
|
||||||
|
{
|
||||||
|
x.update();
|
||||||
|
y.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickBinding::consume_press()
|
||||||
|
{
|
||||||
|
x.consume_press();
|
||||||
|
y.consume_press();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickBinding::consume_release()
|
||||||
|
{
|
||||||
|
x.consume_release();
|
||||||
|
y.consume_release();
|
||||||
|
}
|
||||||
|
|
||||||
|
StickBinding& StickBinding::add_dpad(int controller)
|
||||||
|
{
|
||||||
|
x.negative.add(InputBinding::ButtonBind(controller, Button::Left));
|
||||||
|
x.positive.add(InputBinding::ButtonBind(controller, Button::Right));
|
||||||
|
y.negative.add(InputBinding::ButtonBind(controller, Button::Up));
|
||||||
|
y.positive.add(InputBinding::ButtonBind(controller, Button::Down));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StickBinding& StickBinding::add_left_stick(int controller, float threshold)
|
||||||
|
{
|
||||||
|
x.add_left_stick_x(controller, threshold);
|
||||||
|
y.add_left_stick_y(controller, threshold);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StickBinding& StickBinding::add_right_stick(int controller, float threshold)
|
||||||
|
{
|
||||||
|
x.add_right_stick_x(controller, threshold);
|
||||||
|
y.add_right_stick_y(controller, threshold);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
StickBinding& StickBinding::set_controller(int index)
|
||||||
|
{
|
||||||
|
x.set_controller(index);
|
||||||
|
y.set_controller(index);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickBinding::clear()
|
||||||
|
{
|
||||||
|
x.clear();
|
||||||
|
y.clear();
|
||||||
|
}
|
||||||
|
|
|
@ -1,469 +0,0 @@
|
||||||
#include <blah/input/binding.h>
|
|
||||||
#include <blah/math/calc.h>
|
|
||||||
#include <blah/core/time.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
Binding::TriggerBind::TriggerBind(Axis axis)
|
|
||||||
: axis(axis)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding::TriggerBind::TriggerBind(int controller, Axis axis, float threshold, bool positive)
|
|
||||||
: controller(controller), axis(axis), threshold(threshold), positive(positive)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Binding::TriggerBind::is_down(float axis_value) const
|
|
||||||
{
|
|
||||||
if ((axis_value > 0 && positive) || (axis_value < 0 && !positive))
|
|
||||||
{
|
|
||||||
if (Calc::abs(axis_value) >= threshold)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding::ButtonBind::ButtonBind(Button button)
|
|
||||||
: button(button) {}
|
|
||||||
|
|
||||||
Binding::ButtonBind::ButtonBind(int controller, Button button)
|
|
||||||
: controller(controller), button(button) {}
|
|
||||||
|
|
||||||
bool Binding::pressed() const
|
|
||||||
{
|
|
||||||
if (m_press_consumed)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_last_press_time >= 0 && (Time::seconds - m_last_press_time) <= press_buffer)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return m_pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Binding::released() const
|
|
||||||
{
|
|
||||||
if (m_release_consumed)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_last_release_time >= 0 && (Time::seconds - m_last_release_time) <= release_buffer)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return m_released;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Binding::down() const
|
|
||||||
{
|
|
||||||
return m_down;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Binding::value() const
|
|
||||||
{
|
|
||||||
return m_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Binding::sign() const
|
|
||||||
{
|
|
||||||
return (int)Calc::sign(m_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
double Binding::timestamp() const
|
|
||||||
{
|
|
||||||
return m_last_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Binding::update()
|
|
||||||
{
|
|
||||||
m_press_consumed = false;
|
|
||||||
m_release_consumed = false;
|
|
||||||
|
|
||||||
if (get_pressed())
|
|
||||||
{
|
|
||||||
m_last_timestamp = Time::seconds;
|
|
||||||
m_last_press_time = Time::seconds;
|
|
||||||
m_pressed = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_pressed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_released())
|
|
||||||
{
|
|
||||||
m_last_release_time = Time::seconds;
|
|
||||||
m_released = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_released = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_down = get_down();
|
|
||||||
m_value = get_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Binding::consume_press()
|
|
||||||
{
|
|
||||||
m_press_consumed = true;
|
|
||||||
m_last_press_time = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Binding::consume_release()
|
|
||||||
{
|
|
||||||
m_release_consumed = true;
|
|
||||||
m_last_release_time = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding& Binding::add(Key key)
|
|
||||||
{
|
|
||||||
keys.push_back(key);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding& Binding::add(ButtonBind button)
|
|
||||||
{
|
|
||||||
buttons.push_back(button);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding& Binding::add(TriggerBind trigger)
|
|
||||||
{
|
|
||||||
triggers.push_back(trigger);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding& Binding::add(MouseButton button)
|
|
||||||
{
|
|
||||||
mouse.push_back(button);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding& Binding::add_left_trigger(int controller, float threshold)
|
|
||||||
{
|
|
||||||
triggers.push_back(TriggerBind(controller, Axis::LeftTrigger, threshold, true));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding& Binding::add_right_trigger(int controller, float threshold)
|
|
||||||
{
|
|
||||||
triggers.push_back(TriggerBind(controller, Axis::RightTrigger, threshold, true));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding& Binding::set_controller(int index)
|
|
||||||
{
|
|
||||||
for (auto& it : buttons)
|
|
||||||
it.controller = index;
|
|
||||||
for (auto& it : triggers)
|
|
||||||
it.controller = index;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Binding::clear()
|
|
||||||
{
|
|
||||||
keys.clear();
|
|
||||||
buttons.clear();
|
|
||||||
triggers.clear();
|
|
||||||
mouse.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Binding::get_pressed() const
|
|
||||||
{
|
|
||||||
for (auto& it : keys)
|
|
||||||
if (Input::pressed(it))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : mouse)
|
|
||||||
if (Input::pressed(it))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : buttons)
|
|
||||||
if (Input::pressed(it.controller, it.button))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : triggers)
|
|
||||||
{
|
|
||||||
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (it.is_down(Input::state()->controllers[it.controller].axis[(int)it.axis]) &&
|
|
||||||
!it.is_down(Input::last_state()->controllers[it.controller].axis[(int)it.axis]))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Binding::get_released() const
|
|
||||||
{
|
|
||||||
for (auto& it : keys)
|
|
||||||
if (Input::released(it))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : mouse)
|
|
||||||
if (Input::released(it))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : buttons)
|
|
||||||
if (Input::released(it.controller, it.button))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : triggers)
|
|
||||||
{
|
|
||||||
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!it.is_down(Input::state()->controllers[it.controller].axis[(int)it.axis]) &&
|
|
||||||
it.is_down(Input::last_state()->controllers[it.controller].axis[(int)it.axis]))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Binding::get_down() const
|
|
||||||
{
|
|
||||||
for (auto& it : keys)
|
|
||||||
if (Input::down(it))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : mouse)
|
|
||||||
if (Input::down(it))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : buttons)
|
|
||||||
if (Input::down(it.controller, it.button))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (auto& it : triggers)
|
|
||||||
{
|
|
||||||
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (it.is_down(Input::state()->controllers[it.controller].axis[(int)it.axis]))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Binding::get_value() const
|
|
||||||
{
|
|
||||||
for (auto& it : keys)
|
|
||||||
if (Input::down(it))
|
|
||||||
return 1.0f;
|
|
||||||
|
|
||||||
for (auto& it : mouse)
|
|
||||||
if (Input::down(it))
|
|
||||||
return 1.0f;
|
|
||||||
|
|
||||||
for (auto& it : buttons)
|
|
||||||
if (Input::down(it.controller, it.button))
|
|
||||||
return 1.0f;
|
|
||||||
|
|
||||||
float highest = 0;
|
|
||||||
|
|
||||||
for (auto& it : triggers)
|
|
||||||
{
|
|
||||||
if (it.controller < 0 || it.controller >= Input::max_controllers)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((int)it.axis < 0 || (int)it.axis >= Input::max_controller_axis)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
float raw_value = Input::state()->controllers[it.controller].axis[(int)it.axis];
|
|
||||||
|
|
||||||
if (it.is_down(raw_value))
|
|
||||||
{
|
|
||||||
float mapped_value = Calc::clamped_map(Calc::abs(raw_value), it.threshold, 1.0f, 0.0f, 1.0f);
|
|
||||||
if (mapped_value > highest)
|
|
||||||
highest = mapped_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return highest;
|
|
||||||
}
|
|
||||||
|
|
||||||
float AxisBinding::value() const
|
|
||||||
{
|
|
||||||
float neg = negative.value();
|
|
||||||
float pos = positive.value();
|
|
||||||
|
|
||||||
// neither are down
|
|
||||||
if (neg <= 0 && pos <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// negative-only is down
|
|
||||||
if (neg > 0 && pos <= 0)
|
|
||||||
return -neg;
|
|
||||||
|
|
||||||
// positive-only is down
|
|
||||||
if (pos > 0 && neg <= 0)
|
|
||||||
return pos;
|
|
||||||
|
|
||||||
// both are down:
|
|
||||||
|
|
||||||
// overlap cancel out
|
|
||||||
if (overlap == Overlap::Cancel)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// overlap takes older
|
|
||||||
if (overlap == Overlap::Older)
|
|
||||||
{
|
|
||||||
if (negative.timestamp() < positive.timestamp())
|
|
||||||
return -neg;
|
|
||||||
else
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// overlap takes newer
|
|
||||||
if (negative.timestamp() > positive.timestamp())
|
|
||||||
return -neg;
|
|
||||||
else
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AxisBinding::sign() const
|
|
||||||
{
|
|
||||||
return (int)Calc::sign(value());
|
|
||||||
}
|
|
||||||
|
|
||||||
void AxisBinding::update()
|
|
||||||
{
|
|
||||||
negative.update();
|
|
||||||
positive.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AxisBinding::consume_press()
|
|
||||||
{
|
|
||||||
negative.consume_press();
|
|
||||||
positive.consume_press();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AxisBinding::consume_release()
|
|
||||||
{
|
|
||||||
negative.consume_release();
|
|
||||||
positive.consume_release();
|
|
||||||
}
|
|
||||||
|
|
||||||
AxisBinding& AxisBinding::add_left_stick_x(int controller, float threshold)
|
|
||||||
{
|
|
||||||
negative.add(Binding::TriggerBind(controller, Axis::LeftX, threshold, false));
|
|
||||||
positive.add(Binding::TriggerBind(controller, Axis::LeftX, threshold, true));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AxisBinding& AxisBinding::add_left_stick_y(int controller, float threshold)
|
|
||||||
{
|
|
||||||
negative.add(Binding::TriggerBind(controller, Axis::LeftY, threshold, false));
|
|
||||||
positive.add(Binding::TriggerBind(controller, Axis::LeftY, threshold, true));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AxisBinding& AxisBinding::add_right_stick_x(int controller, float threshold)
|
|
||||||
{
|
|
||||||
negative.add(Binding::TriggerBind(controller, Axis::RightX, threshold, false));
|
|
||||||
positive.add(Binding::TriggerBind(controller, Axis::RightX, threshold, true));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AxisBinding& AxisBinding::add_right_stick_y(int controller, float threshold)
|
|
||||||
{
|
|
||||||
negative.add(Binding::TriggerBind(controller, Axis::RightY, threshold, false));
|
|
||||||
positive.add(Binding::TriggerBind(controller, Axis::RightY, threshold, true));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AxisBinding& AxisBinding::set_controller(int index)
|
|
||||||
{
|
|
||||||
negative.set_controller(index);
|
|
||||||
positive.set_controller(index);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AxisBinding::clear()
|
|
||||||
{
|
|
||||||
negative.clear();
|
|
||||||
positive.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2 StickBinding::value() const
|
|
||||||
{
|
|
||||||
Vec2 result = Vec2(x.value(), y.value());
|
|
||||||
if (round_threshold > 0 && result.length() < round_threshold)
|
|
||||||
return Vec2::zero;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point StickBinding::sign() const
|
|
||||||
{
|
|
||||||
Vec2 result = value();
|
|
||||||
return Point((int)Calc::sign(result.x), (int)Calc::sign(result.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickBinding::update()
|
|
||||||
{
|
|
||||||
x.update();
|
|
||||||
y.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickBinding::consume_press()
|
|
||||||
{
|
|
||||||
x.consume_press();
|
|
||||||
y.consume_press();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickBinding::consume_release()
|
|
||||||
{
|
|
||||||
x.consume_release();
|
|
||||||
y.consume_release();
|
|
||||||
}
|
|
||||||
|
|
||||||
StickBinding& StickBinding::add_dpad(int controller)
|
|
||||||
{
|
|
||||||
x.negative.add(Binding::ButtonBind(controller, Button::Left));
|
|
||||||
x.positive.add(Binding::ButtonBind(controller, Button::Right));
|
|
||||||
y.negative.add(Binding::ButtonBind(controller, Button::Up));
|
|
||||||
y.positive.add(Binding::ButtonBind(controller, Button::Down));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StickBinding& StickBinding::add_left_stick(int controller, float threshold)
|
|
||||||
{
|
|
||||||
x.add_left_stick_x(controller, threshold);
|
|
||||||
y.add_left_stick_y(controller, threshold);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StickBinding& StickBinding::add_right_stick(int controller, float threshold)
|
|
||||||
{
|
|
||||||
x.add_right_stick_x(controller, threshold);
|
|
||||||
y.add_right_stick_y(controller, threshold);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StickBinding& StickBinding::set_controller(int index)
|
|
||||||
{
|
|
||||||
x.set_controller(index);
|
|
||||||
y.set_controller(index);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickBinding::clear()
|
|
||||||
{
|
|
||||||
x.clear();
|
|
||||||
y.clear();
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
#include <blah/input/binding_registry.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
Vector<std::weak_ptr<Binding>> BindingRegistry::bindings;
|
|
||||||
Vector<std::weak_ptr<AxisBinding>> BindingRegistry::axes;
|
|
||||||
Vector<std::weak_ptr<StickBinding>> BindingRegistry::sticks;
|
|
||||||
|
|
||||||
BindingRef BindingRegistry::register_binding(const Binding& binding)
|
|
||||||
{
|
|
||||||
auto result = std::make_shared<Binding>(binding);
|
|
||||||
bindings.push_back(std::weak_ptr<Binding>(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
AxisBindingRef BindingRegistry::register_axis(const AxisBinding& binding)
|
|
||||||
{
|
|
||||||
auto result = std::make_shared<AxisBinding>(binding);
|
|
||||||
axes.push_back(std::weak_ptr<AxisBinding>(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
StickBindingRef BindingRegistry::register_stick(const StickBinding& binding)
|
|
||||||
{
|
|
||||||
auto result = std::make_shared<StickBinding>(binding);
|
|
||||||
sticks.push_back(std::weak_ptr<StickBinding>(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BindingRegistry::update()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < bindings.size(); i++)
|
|
||||||
{
|
|
||||||
if (bindings[i].use_count() <= 0)
|
|
||||||
{
|
|
||||||
bindings.erase(i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
else if (auto binding = bindings[i].lock())
|
|
||||||
{
|
|
||||||
binding->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < axes.size(); i++)
|
|
||||||
{
|
|
||||||
if (axes[i].use_count() <= 0)
|
|
||||||
{
|
|
||||||
axes.erase(i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
else if (auto binding = axes[i].lock())
|
|
||||||
{
|
|
||||||
binding->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < sticks.size(); i++)
|
|
||||||
{
|
|
||||||
if (sticks[i].use_count() <= 0)
|
|
||||||
{
|
|
||||||
sticks.erase(i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
else if (auto binding = sticks[i].lock())
|
|
||||||
{
|
|
||||||
binding->update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,406 +0,0 @@
|
||||||
#include <blah/input/input.h>
|
|
||||||
#include <blah/input/binding_registry.h>
|
|
||||||
#include <blah/core/app.h>
|
|
||||||
#include <blah/core/time.h>
|
|
||||||
#include <blah/core/common.h>
|
|
||||||
#include <blah/math/point.h>
|
|
||||||
#include "../internal/input_backend.h"
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
InputState g_last_state;
|
|
||||||
InputState g_curr_state;
|
|
||||||
InputState g_next_state;
|
|
||||||
InputState g_empty_state;
|
|
||||||
ControllerState g_empty_controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::init()
|
|
||||||
{
|
|
||||||
g_empty_controller.name = "Disconnected";
|
|
||||||
for (int i = 0; i < Blah::Input::max_controllers; i++)
|
|
||||||
g_empty_state.controllers[i].name = g_empty_controller.name;
|
|
||||||
|
|
||||||
g_last_state = g_empty_state;
|
|
||||||
g_curr_state = g_empty_state;
|
|
||||||
g_next_state = g_empty_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::frame()
|
|
||||||
{
|
|
||||||
// cycle states
|
|
||||||
g_last_state = g_curr_state;
|
|
||||||
g_curr_state = g_next_state;
|
|
||||||
|
|
||||||
// copy state, clear pressed / released values
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Blah::Input::max_keyboard_keys; i++)
|
|
||||||
{
|
|
||||||
g_next_state.keyboard.pressed[i] = false;
|
|
||||||
g_next_state.keyboard.released[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < Blah::Input::max_mouse_buttons; i++)
|
|
||||||
{
|
|
||||||
g_next_state.mouse.pressed[i] = false;
|
|
||||||
g_next_state.mouse.released[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_next_state.mouse.wheel = Point::zero;
|
|
||||||
g_next_state.keyboard.text.clear();
|
|
||||||
|
|
||||||
for (int i = 0; i < Blah::Input::max_controllers; i++)
|
|
||||||
{
|
|
||||||
ControllerState* controller = &(g_next_state.controllers[i]);
|
|
||||||
|
|
||||||
if (!controller->is_connected)
|
|
||||||
controller->name = nullptr;
|
|
||||||
|
|
||||||
for (int j = 0; j < Blah::Input::max_controller_buttons; j++)
|
|
||||||
{
|
|
||||||
controller->pressed[j] = false;
|
|
||||||
controller->released[j] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update bindings
|
|
||||||
BindingRegistry::update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_mouse_move(float x, float y)
|
|
||||||
{
|
|
||||||
g_next_state.mouse.position.x = x;
|
|
||||||
g_next_state.mouse.position.y = y;
|
|
||||||
|
|
||||||
Point size = Point(App::width(), App::height());
|
|
||||||
Point draw = Point(App::draw_width(), App::draw_height());
|
|
||||||
|
|
||||||
g_next_state.mouse.draw_position.x = (x / (float)size.x) * draw.x;
|
|
||||||
g_next_state.mouse.draw_position.y = (y / (float)size.y) * draw.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_mouse_screen_move(float x, float y)
|
|
||||||
{
|
|
||||||
g_next_state.mouse.screen_position.x = x;
|
|
||||||
g_next_state.mouse.screen_position.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_mouse_down(MouseButton button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
if (i >= 0 && i < Blah::Input::max_mouse_buttons)
|
|
||||||
{
|
|
||||||
g_next_state.mouse.down[i] = true;
|
|
||||||
g_next_state.mouse.pressed[i] = true;
|
|
||||||
g_next_state.mouse.timestamp[i] = Time::ticks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_mouse_up(MouseButton button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
if (i >= 0 && i < Blah::Input::max_mouse_buttons)
|
|
||||||
{
|
|
||||||
g_next_state.mouse.down[i] = false;
|
|
||||||
g_next_state.mouse.released[i] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_key_down(Key key)
|
|
||||||
{
|
|
||||||
int i = (int)key;
|
|
||||||
if (i >= 0 && i < Blah::Input::max_keyboard_keys)
|
|
||||||
{
|
|
||||||
g_next_state.keyboard.down[i] = true;
|
|
||||||
g_next_state.keyboard.pressed[i] = true;
|
|
||||||
g_next_state.keyboard.timestamp[i] = Time::ticks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_mouse_wheel(Point wheel)
|
|
||||||
{
|
|
||||||
g_next_state.mouse.wheel = wheel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_key_up(Key key)
|
|
||||||
{
|
|
||||||
int i = (int)key;
|
|
||||||
if (i >= 0 && i < Blah::Input::max_keyboard_keys)
|
|
||||||
{
|
|
||||||
g_next_state.keyboard.down[i] = false;
|
|
||||||
g_next_state.keyboard.released[i] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_text_utf8(const char* text)
|
|
||||||
{
|
|
||||||
g_next_state.keyboard.text += text;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_controller_connect(int index, const char* name, int is_gamepad, int button_count, int axis_count, u16 vendor, u16 product, u16 version)
|
|
||||||
{
|
|
||||||
if (index < Blah::Input::max_controllers)
|
|
||||||
{
|
|
||||||
ControllerState* controller = &(g_next_state.controllers[index]);
|
|
||||||
*controller = g_empty_controller;
|
|
||||||
controller->name = name;
|
|
||||||
controller->is_connected = true;
|
|
||||||
controller->is_gamepad = is_gamepad;
|
|
||||||
controller->button_count = button_count;
|
|
||||||
controller->axis_count = axis_count;
|
|
||||||
controller->vendor = vendor;
|
|
||||||
controller->product = product;
|
|
||||||
controller->version = version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_controller_disconnect(int index)
|
|
||||||
{
|
|
||||||
if (index < Blah::Input::max_controllers)
|
|
||||||
g_next_state.controllers[index] = g_empty_controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_button_down(int index, int button)
|
|
||||||
{
|
|
||||||
if (index < Blah::Input::max_controllers &&
|
|
||||||
button < Blah::Input::max_controller_buttons &&
|
|
||||||
g_next_state.controllers[index].is_connected &&
|
|
||||||
button < g_next_state.controllers[index].button_count)
|
|
||||||
{
|
|
||||||
g_next_state.controllers[index].down[button] = true;
|
|
||||||
g_next_state.controllers[index].pressed[button] = true;
|
|
||||||
g_next_state.controllers[index].button_timestamp[button] = Time::ticks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_button_up(int index, int button)
|
|
||||||
{
|
|
||||||
if (index < Blah::Input::max_controllers &&
|
|
||||||
button < Blah::Input::max_controller_buttons &&
|
|
||||||
g_next_state.controllers[index].is_connected &&
|
|
||||||
button < g_next_state.controllers[index].button_count)
|
|
||||||
{
|
|
||||||
g_next_state.controllers[index].down[button] = false;
|
|
||||||
g_next_state.controllers[index].released[button] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputBackend::on_axis_move(int index, int axis, float value)
|
|
||||||
{
|
|
||||||
if (index < Blah::Input::max_controllers &&
|
|
||||||
axis < Blah::Input::max_controller_axis &&
|
|
||||||
g_next_state.controllers[index].is_connected &&
|
|
||||||
axis < g_next_state.controllers[index].axis_count)
|
|
||||||
{
|
|
||||||
g_next_state.controllers[index].axis[axis] = value;
|
|
||||||
g_next_state.controllers[index].axis_timestamp[axis] = Time::ticks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const InputState* Input::state()
|
|
||||||
{
|
|
||||||
return &g_curr_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
const InputState* Input::last_state()
|
|
||||||
{
|
|
||||||
return &g_last_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2 Input::mouse()
|
|
||||||
{
|
|
||||||
return g_curr_state.mouse.position;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Vec2 Input::mouse_draw()
|
|
||||||
{
|
|
||||||
return Vec2(g_curr_state.mouse.draw_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec2 Input::mouse_screen()
|
|
||||||
{
|
|
||||||
return Vec2(g_curr_state.mouse.screen_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::pressed(MouseButton button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.pressed[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::down(MouseButton button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.down[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::released(MouseButton button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
return i >= 0 && i < Blah::Input::max_mouse_buttons&& g_curr_state.mouse.released[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
Point Input::mouse_wheel()
|
|
||||||
{
|
|
||||||
return g_curr_state.mouse.wheel;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::pressed(Key key)
|
|
||||||
{
|
|
||||||
int i = (int)key;
|
|
||||||
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.pressed[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::down(Key key)
|
|
||||||
{
|
|
||||||
int i = (int)key;
|
|
||||||
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.down[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::released(Key key)
|
|
||||||
{
|
|
||||||
int i = (int)key;
|
|
||||||
return i > 0 && i < Blah::Input::max_keyboard_keys&& g_curr_state.keyboard.released[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::ctrl()
|
|
||||||
{
|
|
||||||
return down(Key::LeftControl) || down(Key::RightControl);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::shift()
|
|
||||||
{
|
|
||||||
return down(Key::LeftShift) || down(Key::RightShift);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::alt()
|
|
||||||
{
|
|
||||||
return down(Key::LeftAlt) || down(Key::RightAlt);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Input::text()
|
|
||||||
{
|
|
||||||
return g_curr_state.keyboard.text;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ControllerState* Input::controller(int controllerIndex)
|
|
||||||
{
|
|
||||||
if (controllerIndex >= Blah::Input::max_controllers)
|
|
||||||
{
|
|
||||||
Log::warn("Trying to access a out-of-range controller at %i", controllerIndex);
|
|
||||||
return &g_empty_controller;
|
|
||||||
}
|
|
||||||
else if (!g_curr_state.controllers[controllerIndex].is_connected)
|
|
||||||
{
|
|
||||||
return &g_empty_controller;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return &g_curr_state.controllers[controllerIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::pressed(int controllerIndex, Button button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
|
|
||||||
return g_curr_state.controllers[controllerIndex].pressed[i];
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::down(int controllerIndex, Button button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
|
|
||||||
return g_curr_state.controllers[controllerIndex].down[i];
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Input::released(int controllerIndex, Button button)
|
|
||||||
{
|
|
||||||
int i = (int)button;
|
|
||||||
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_buttons)
|
|
||||||
return g_curr_state.controllers[controllerIndex].released[i];
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Input::axis_check(int controllerIndex, Axis axis)
|
|
||||||
{
|
|
||||||
int i = (int)axis;
|
|
||||||
if (controllerIndex < Blah::Input::max_controllers && i >= 0 && i < Blah::Input::max_controller_axis)
|
|
||||||
return g_curr_state.controllers[controllerIndex].axis[i];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Input::axis_check(int fallback, Key negative, Key positive)
|
|
||||||
{
|
|
||||||
if (Input::pressed(positive))
|
|
||||||
return 1;
|
|
||||||
else if (Input::pressed(negative))
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool pos = Input::down(positive);
|
|
||||||
bool neg = Input::down(negative);
|
|
||||||
|
|
||||||
if (pos && neg)
|
|
||||||
return fallback;
|
|
||||||
else if (pos)
|
|
||||||
return 1;
|
|
||||||
else if (neg)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Input::axis_check(int fallback, int controllerIndex, Button negative, Button positive)
|
|
||||||
{
|
|
||||||
if (Input::pressed(controllerIndex, positive))
|
|
||||||
return 1;
|
|
||||||
else if (Input::pressed(controllerIndex, negative))
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool pos = Input::down(controllerIndex, positive);
|
|
||||||
bool neg = Input::down(controllerIndex, negative);
|
|
||||||
|
|
||||||
if (pos && neg)
|
|
||||||
return fallback;
|
|
||||||
else if (pos)
|
|
||||||
return 1;
|
|
||||||
else if (neg)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Input::name_of(Key key)
|
|
||||||
{
|
|
||||||
switch (key)
|
|
||||||
{
|
|
||||||
#define DEFINE_KEY(name, value) case Key::name: return #name;
|
|
||||||
BLAH_KEY_DEFINITIONS
|
|
||||||
#undef DEFINE_KEY
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Input::name_of(Button button)
|
|
||||||
{
|
|
||||||
switch (button)
|
|
||||||
{
|
|
||||||
#define DEFINE_BTN(name, value) case Button::name: return #name;
|
|
||||||
BLAH_BUTTON_DEFINITIONS
|
|
||||||
#undef DEFINE_BTN
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/app.h>
|
#include <blah/app.h>
|
||||||
#include <blah/graphics/renderpass.h>
|
#include <blah/graphics/renderpass.h>
|
||||||
#include <blah/graphics/texture.h>
|
#include <blah/graphics/texture.h>
|
||||||
#include <blah/graphics/framebuffer.h>
|
#include <blah/graphics/target.h>
|
||||||
#include <blah/graphics/shader.h>
|
#include <blah/graphics/shader.h>
|
||||||
#include <blah/graphics/mesh.h>
|
#include <blah/graphics/mesh.h>
|
||||||
#include <blah/graphics/material.h>
|
#include <blah/graphics/material.h>
|
||||||
#include <blah/math/color.h>
|
#include <blah/numerics/color.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -45,9 +45,9 @@ namespace Blah
|
||||||
// if the Texture is invalid, this should return an empty reference.
|
// if the Texture is invalid, this should return an empty reference.
|
||||||
TextureRef create_texture(int width, int height, TextureFormat format);
|
TextureRef create_texture(int width, int height, TextureFormat format);
|
||||||
|
|
||||||
// Creates a new FrameBuffer.
|
// Creates a new Target.
|
||||||
// if the FrameBuffer is invalid, this should return an empty reference.
|
// if the Target is invalid, this should return an empty reference.
|
||||||
FrameBufferRef create_framebuffer(int width, int height, const TextureFormat* attachments, int attachment_count);
|
TargetRef create_target(int width, int height, const TextureFormat* attachments, int attachment_count);
|
||||||
|
|
||||||
// Creates a new Shader.
|
// Creates a new Shader.
|
||||||
// if the Shader is invalid, this should return an empty reference.
|
// if the Shader is invalid, this should return an empty reference.
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "../internal/graphics_backend.h"
|
#include "../internal/graphics_backend.h"
|
||||||
#include "../internal/platform_backend.h"
|
#include "../internal/platform_backend.h"
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
@ -252,7 +252,7 @@ namespace Blah
|
||||||
hr = state.device->CreateTexture2D(&desc, NULL, &staging);
|
hr = state.device->CreateTexture2D(&desc, NULL, &staging);
|
||||||
if (!SUCCEEDED(hr))
|
if (!SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Failed to create staging texture to get data");
|
BLAH_ASSERT(false, "Failed to create staging texture to get data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ namespace Blah
|
||||||
|
|
||||||
if (!SUCCEEDED(hr))
|
if (!SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
BLAH_ERROR("Failed to get texture data");
|
BLAH_ASSERT(false, "Failed to get texture data");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,16 +285,16 @@ namespace Blah
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class D3D11_FrameBuffer : public FrameBuffer
|
class D3D11_Target : public Target
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Attachments m_attachments;
|
Attachments m_attachments;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StackVector<ID3D11RenderTargetView*, Attachments::MaxCapacity - 1> color_views;
|
StackVector<ID3D11RenderTargetView*, Attachments::capacity - 1> color_views;
|
||||||
ID3D11DepthStencilView* depth_view = nullptr;
|
ID3D11DepthStencilView* depth_view = nullptr;
|
||||||
|
|
||||||
D3D11_FrameBuffer(int width, int height, const TextureFormat* attachments, int attachment_count)
|
D3D11_Target(int width, int height, const TextureFormat* attachments, int attachment_count)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < attachment_count; i++)
|
for (int i = 0; i < attachment_count; i++)
|
||||||
{
|
{
|
||||||
|
@ -315,19 +315,19 @@ namespace Blah
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~D3D11_FrameBuffer()
|
~D3D11_Target()
|
||||||
{
|
{
|
||||||
for (auto& it : color_views)
|
for (auto& it : color_views)
|
||||||
it->Release();
|
it->Release();
|
||||||
color_views.clear();
|
color_views.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Attachments& attachments() override
|
Attachments& textures() override
|
||||||
{
|
{
|
||||||
return m_attachments;
|
return m_attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Attachments& attachments() const override
|
const Attachments& textures() const override
|
||||||
{
|
{
|
||||||
return m_attachments;
|
return m_attachments;
|
||||||
}
|
}
|
||||||
|
@ -841,9 +841,9 @@ namespace Blah
|
||||||
return TextureRef();
|
return TextureRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBufferRef GraphicsBackend::create_framebuffer(int width, int height, const TextureFormat* attachments, int attachment_count)
|
TargetRef GraphicsBackend::create_target(int width, int height, const TextureFormat* attachments, int attachment_count)
|
||||||
{
|
{
|
||||||
return FrameBufferRef(new D3D11_FrameBuffer(width, height, attachments, attachment_count));
|
return TargetRef(new D3D11_Target(width, height, attachments, attachment_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderRef GraphicsBackend::create_shader(const ShaderData* data)
|
ShaderRef GraphicsBackend::create_shader(const ShaderData* data)
|
||||||
|
@ -876,7 +876,7 @@ namespace Blah
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto target = (D3D11_FrameBuffer*)(pass.target.get());
|
auto target = (D3D11_Target*)(pass.target.get());
|
||||||
ctx->OMSetRenderTargets(target->color_views.size(), target->color_views.begin(), target->depth_view);
|
ctx->OMSetRenderTargets(target->color_views.size(), target->color_views.begin(), target->depth_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include "../internal/graphics_backend.h"
|
#include "../internal/graphics_backend.h"
|
||||||
#include "../internal/platform_backend.h"
|
#include "../internal/platform_backend.h"
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
@ -56,14 +56,14 @@ namespace Blah
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Dummy_FrameBuffer : public FrameBuffer
|
class Dummy_Target : public Target
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Attachments m_attachments;
|
Attachments m_attachments;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Dummy_FrameBuffer(int width, int height, const TextureFormat* attachments, int attachmentCount)
|
Dummy_Target(int width, int height, const TextureFormat* attachments, int attachmentCount)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < attachmentCount; i++)
|
for (int i = 0; i < attachmentCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -73,12 +73,12 @@ namespace Blah
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Attachments& attachments() override
|
virtual Attachments& textures() override
|
||||||
{
|
{
|
||||||
return m_attachments;
|
return m_attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const Attachments& attachments() const override
|
virtual const Attachments& textures() const override
|
||||||
{
|
{
|
||||||
return m_attachments;
|
return m_attachments;
|
||||||
}
|
}
|
||||||
|
@ -186,9 +186,9 @@ namespace Blah
|
||||||
return TextureRef(new Dummy_Texture(width, height, format, false));
|
return TextureRef(new Dummy_Texture(width, height, format, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBufferRef GraphicsBackend::create_framebuffer(int width, int height, const TextureFormat* attachments, int attachmentCount)
|
TargetRef GraphicsBackend::create_target(int width, int height, const TextureFormat* attachments, int attachmentCount)
|
||||||
{
|
{
|
||||||
return FrameBufferRef(new Dummy_FrameBuffer(width, height, attachments, attachmentCount));
|
return TargetRef(new Dummy_Target(width, height, attachments, attachmentCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderRef GraphicsBackend::create_shader(const ShaderData* data)
|
ShaderRef GraphicsBackend::create_shader(const ShaderData* data)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/input/input.h>
|
#include <blah/input.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include <blah/core/filesystem.h>
|
#include <blah/filesystem.h>
|
||||||
#include <blah/containers/vector.h>
|
#include <blah/containers/vector.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
|
@ -66,6 +66,9 @@ namespace Blah
|
||||||
// Returns the absolute path to the user directory where save data and settings should be stored
|
// Returns the absolute path to the user directory where save data and settings should be stored
|
||||||
const char* user_path();
|
const char* user_path();
|
||||||
|
|
||||||
|
// Opens a file and sets the handle, or returns an empty handle if it fails
|
||||||
|
FileRef file_open(const char* path, FileMode mode);
|
||||||
|
|
||||||
// Returns true if a file with the given path exists
|
// Returns true if a file with the given path exists
|
||||||
bool file_exists(const char* path);
|
bool file_exists(const char* path);
|
||||||
|
|
||||||
|
@ -87,27 +90,6 @@ namespace Blah
|
||||||
// opens a directory in the OS file explorer / finder
|
// opens a directory in the OS file explorer / finder
|
||||||
void dir_explore(const char* path);
|
void dir_explore(const char* path);
|
||||||
|
|
||||||
// Opens a file and sets the handle. returns true if the file was successfully opened
|
|
||||||
bool file_open(const char* path, FileHandle* handle, FileMode mode);
|
|
||||||
|
|
||||||
// Returns the length of the file
|
|
||||||
i64 file_length(FileHandle file);
|
|
||||||
|
|
||||||
// Returns the Position of the file
|
|
||||||
i64 file_position(FileHandle file);
|
|
||||||
|
|
||||||
// Seeks the Position of the file and returns the new position from the start of the file
|
|
||||||
i64 file_seek(FileHandle file, i64 seekTo);
|
|
||||||
|
|
||||||
// Reads a specific number of elements of a given size from the file into ptr
|
|
||||||
i64 file_read(FileHandle file, void* ptr, i64 size);
|
|
||||||
|
|
||||||
// Writes a specific number of elements of the given size from ptr to the file
|
|
||||||
i64 file_write(FileHandle file, const void* ptr, i64 size);
|
|
||||||
|
|
||||||
// Closes a file
|
|
||||||
void file_close(FileHandle file);
|
|
||||||
|
|
||||||
// OpenGL Methods
|
// OpenGL Methods
|
||||||
void* gl_get_func(const char* name);
|
void* gl_get_func(const char* name);
|
||||||
void* gl_context_create();
|
void* gl_context_create();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,25 +0,0 @@
|
||||||
#include <blah/math/stopwatch.h>
|
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
using namespace std::chrono;
|
|
||||||
using namespace Blah;
|
|
||||||
|
|
||||||
Stopwatch::Stopwatch()
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stopwatch::reset()
|
|
||||||
{
|
|
||||||
start_time = std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count();
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 Stopwatch::milliseconds()
|
|
||||||
{
|
|
||||||
return microseconds() / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 Stopwatch::microseconds()
|
|
||||||
{
|
|
||||||
return std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count() - start_time;
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/math/circle.h>
|
#include <blah/numerics/circle.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <blah/math/color.h>
|
#include <blah/numerics/color.h>
|
||||||
#include <blah/math/vec3.h>
|
#include <blah/numerics/vec3.h>
|
||||||
#include <blah/math/vec4.h>
|
#include <blah/numerics/vec4.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <blah/math/line.h>
|
#include <blah/numerics/line.h>
|
||||||
#include <blah/math/rect.h>
|
#include <blah/numerics/rect.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <blah/math/mat3x2.h>
|
#include <blah/numerics/mat3x2.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
|
#include <blah/numerics/calc.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
@ -132,8 +132,8 @@ Mat3x2 Mat3x2::create_scale(float scaleX, float scaleY, Vec2 centerPoint)
|
||||||
|
|
||||||
Mat3x2 Mat3x2::create_rotation(float radians)
|
Mat3x2 Mat3x2::create_rotation(float radians)
|
||||||
{
|
{
|
||||||
float c = cosf(radians);
|
float c = Calc::cos(radians);
|
||||||
float s = sinf(radians);
|
float s = Calc::sin(radians);
|
||||||
|
|
||||||
return Mat3x2(c, s, -s, c, 0, 0);
|
return Mat3x2(c, s, -s, c, 0, 0);
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/math/mat4x4.h>
|
#include <blah/numerics/mat4x4.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/math/mat3x2.h>
|
#include <blah/numerics/mat3x2.h>
|
||||||
#include <math.h>
|
#include <blah/numerics/calc.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ bool Point::operator !=(const Point& rhs) { return x != rhs.x || y != rhs.y; }
|
||||||
|
|
||||||
float Point::length() const
|
float Point::length() const
|
||||||
{
|
{
|
||||||
return sqrtf((float)(x * x + y * y));
|
return Calc::sqrt((float)(x * x + y * y));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Point::length_squared() const
|
int Point::length_squared() const
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/math/quad.h>
|
#include <blah/numerics/quad.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
|
|
||||||
namespace Blah
|
namespace Blah
|
||||||
{
|
{
|
|
@ -1,9 +1,9 @@
|
||||||
#include <blah/math/rect.h>
|
#include <blah/numerics/rect.h>
|
||||||
#include <blah/math/point.h>
|
#include <blah/numerics/point.h>
|
||||||
#include <blah/math/rectI.h>
|
#include <blah/numerics/rectI.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
#include <blah/math/mat3x2.h>
|
#include <blah/numerics/mat3x2.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include <blah/math/rectI.h>
|
#include <blah/numerics/rectI.h>
|
||||||
#include <blah/math/rect.h>
|
#include <blah/numerics/rect.h>
|
||||||
#include <blah/math/point.h>
|
#include <blah/numerics/point.h>
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include <blah/math/vec2.h>
|
#include <blah/numerics/vec2.h>
|
||||||
#include <blah/math/mat3x2.h>
|
#include <blah/numerics/mat3x2.h>
|
||||||
#include <blah/math/calc.h>
|
#include <blah/numerics/calc.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
|
@ -42,7 +42,7 @@ BufferStream::~BufferStream()
|
||||||
delete[] m_buffer;
|
delete[] m_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 BufferStream::read_into(void* ptr, i64 len)
|
size_t BufferStream::read_into(void* ptr, size_t len)
|
||||||
{
|
{
|
||||||
if (m_buffer == nullptr || ptr == nullptr)
|
if (m_buffer == nullptr || ptr == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -58,7 +58,7 @@ i64 BufferStream::read_into(void* ptr, i64 len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 BufferStream::write_from(const void* ptr, i64 len)
|
size_t BufferStream::write_from(const void* ptr, size_t len)
|
||||||
{
|
{
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -78,7 +78,7 @@ i64 BufferStream::write_from(const void* ptr, i64 len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferStream::resize(i64 length)
|
void BufferStream::resize(size_t length)
|
||||||
{
|
{
|
||||||
if (m_capacity > length)
|
if (m_capacity > length)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <blah/streams/filestream.h>
|
#include <blah/streams/filestream.h>
|
||||||
#include <blah/core/common.h>
|
#include <blah/common.h>
|
||||||
#include "../internal/platform_backend.h"
|
#include "../internal/platform_backend.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
@ -7,105 +7,90 @@ using namespace Blah;
|
||||||
|
|
||||||
FileStream::FileStream()
|
FileStream::FileStream()
|
||||||
{
|
{
|
||||||
m_handle = nullptr;
|
|
||||||
m_mode = FileMode::OpenRead;
|
m_mode = FileMode::OpenRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream::FileStream(const FilePath& path, FileMode mode)
|
FileStream::FileStream(const FilePath& path, FileMode mode)
|
||||||
: m_mode(mode)
|
: m_mode(mode)
|
||||||
|
, m_file(File::open(path, mode))
|
||||||
{
|
{
|
||||||
if (!PlatformBackend::file_open(path, &m_handle, mode))
|
|
||||||
m_handle = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream::FileStream(FileStream&& src) noexcept
|
FileStream::FileStream(FileStream&& src) noexcept
|
||||||
{
|
{
|
||||||
m_handle = src.m_handle;
|
m_file = src.m_file;
|
||||||
m_mode = src.m_mode;
|
m_mode = src.m_mode;
|
||||||
src.m_handle = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream& FileStream::operator=(FileStream&& src) noexcept
|
FileStream& FileStream::operator=(FileStream&& src) noexcept
|
||||||
{
|
{
|
||||||
m_handle = src.m_handle;
|
m_file = src.m_file;
|
||||||
m_mode = src.m_mode;
|
m_mode = src.m_mode;
|
||||||
src.m_handle = nullptr;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStream::~FileStream()
|
size_t FileStream::length() const
|
||||||
{
|
{
|
||||||
if (m_handle != nullptr)
|
if (m_file)
|
||||||
PlatformBackend::file_close(m_handle);
|
return m_file->length();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 FileStream::length() const
|
size_t FileStream::position() const
|
||||||
{
|
{
|
||||||
if (m_handle == nullptr)
|
if (m_file)
|
||||||
return 0;
|
return m_file->position();
|
||||||
|
return 0;
|
||||||
return PlatformBackend::file_length(m_handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 FileStream::position() const
|
size_t FileStream::seek(size_t seek_to)
|
||||||
{
|
{
|
||||||
if (m_handle == nullptr)
|
if (m_file)
|
||||||
return 0;
|
return m_file->seek(seek_to);
|
||||||
|
return 0;
|
||||||
return PlatformBackend::file_position(m_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
i64 FileStream::seek(i64 seek_to)
|
|
||||||
{
|
|
||||||
if (m_handle == nullptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return PlatformBackend::file_seek(m_handle, seek_to);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileStream::is_open() const
|
bool FileStream::is_open() const
|
||||||
{
|
{
|
||||||
return m_handle != nullptr;
|
return m_file.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileStream::is_readable() const
|
bool FileStream::is_readable() const
|
||||||
{
|
{
|
||||||
return m_handle != nullptr && (m_mode != FileMode::CreateWrite);
|
return m_file.get() && (m_mode != FileMode::CreateWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileStream::is_writable() const
|
bool FileStream::is_writable() const
|
||||||
{
|
{
|
||||||
return m_handle != nullptr && (m_mode != FileMode::OpenRead);
|
return m_file.get() && (m_mode != FileMode::OpenRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 FileStream::read_into(void* ptr, i64 length)
|
size_t FileStream::read_into(void* ptr, size_t length)
|
||||||
{
|
|
||||||
if (m_handle == nullptr)
|
|
||||||
{
|
|
||||||
BLAH_ERROR("Unable to read from Stream");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PlatformBackend::file_read(m_handle, ptr, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
i64 FileStream::write_from(const void* ptr, i64 length)
|
|
||||||
{
|
{
|
||||||
if (length <= 0)
|
if (length <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (m_handle == nullptr)
|
if (m_file)
|
||||||
{
|
return m_file->read((unsigned char*)ptr, length);
|
||||||
BLAH_ERROR("Unable to write to Stream");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PlatformBackend::file_write(m_handle, ptr, length);
|
BLAH_ASSERT(false, "Unable to read from Stream");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FileStream::write_from(const void* ptr, size_t length)
|
||||||
|
{
|
||||||
|
if (length <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (m_file)
|
||||||
|
return m_file->write((const unsigned char*)ptr, length);
|
||||||
|
|
||||||
|
BLAH_ASSERT(false, "Unable to write to Stream");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileStream::close()
|
void FileStream::close()
|
||||||
{
|
{
|
||||||
if (m_handle != nullptr)
|
m_file.reset();
|
||||||
PlatformBackend::file_close(m_handle);
|
|
||||||
m_handle = nullptr;
|
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ using namespace Blah;
|
||||||
MemoryStream::MemoryStream()
|
MemoryStream::MemoryStream()
|
||||||
: m_data(nullptr), m_length(0), m_position(0) {}
|
: m_data(nullptr), m_length(0), m_position(0) {}
|
||||||
|
|
||||||
MemoryStream::MemoryStream(char* data, i64 length)
|
MemoryStream::MemoryStream(char* data, size_t length)
|
||||||
: m_data(data), m_length(length), m_position(0) {}
|
: m_data(data), m_length(length), m_position(0) {}
|
||||||
|
|
||||||
MemoryStream::MemoryStream(MemoryStream&& src) noexcept
|
MemoryStream::MemoryStream(MemoryStream&& src) noexcept
|
||||||
|
@ -28,7 +28,7 @@ MemoryStream& MemoryStream::operator=(MemoryStream&& src) noexcept
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 MemoryStream::read_into(void* ptr, i64 len)
|
size_t MemoryStream::read_into(void* ptr, size_t len)
|
||||||
{
|
{
|
||||||
if (len < 0 || ptr == nullptr)
|
if (len < 0 || ptr == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -41,7 +41,7 @@ i64 MemoryStream::read_into(void* ptr, i64 len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 MemoryStream::write_from(const void* ptr, i64 len)
|
size_t MemoryStream::write_from(const void* ptr, size_t len)
|
||||||
{
|
{
|
||||||
if (len < 0 || ptr == nullptr)
|
if (len < 0 || ptr == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
|
||||||
i64 Stream::pipe(Stream& stream, i64 length)
|
size_t Stream::pipe(Stream& stream, size_t length)
|
||||||
{
|
{
|
||||||
const int BUFFER_LENGTH = 4096;
|
const int BUFFER_LENGTH = 4096;
|
||||||
i64 result = 0;
|
size_t result = 0;
|
||||||
|
|
||||||
char buffer[BUFFER_LENGTH];
|
char buffer[BUFFER_LENGTH];
|
||||||
while (length > 0)
|
while (length > 0)
|
||||||
|
@ -59,12 +59,12 @@ String Stream::read_line()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 Stream::write(const void* buffer, i64 length)
|
size_t Stream::write(const void* buffer, size_t length)
|
||||||
{
|
{
|
||||||
return write_from(buffer, length);
|
return write_from(buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 Stream::write(const String& string)
|
size_t Stream::write(const String& string)
|
||||||
{
|
{
|
||||||
return write_from(string.begin(), string.length());
|
return write_from(string.begin(), string.length());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
#include <blah/core/time.h>
|
#include <blah/time.h>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
using namespace Blah;
|
using namespace Blah;
|
||||||
|
using namespace std::chrono;
|
||||||
namespace
|
|
||||||
{
|
|
||||||
double modf(double x, double m)
|
|
||||||
{
|
|
||||||
return x - (int)(x / m) * m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 Time::ticks = 0;
|
u64 Time::ticks = 0;
|
||||||
u64 Time::previous_ticks = 0;
|
u64 Time::previous_ticks = 0;
|
||||||
|
@ -48,6 +42,11 @@ bool Time::on_time(double time, double timestamp)
|
||||||
|
|
||||||
bool Time::between_interval(double time, float interval, float offset)
|
bool Time::between_interval(double time, float interval, float offset)
|
||||||
{
|
{
|
||||||
|
static const auto modf = [](double x, double m)
|
||||||
|
{
|
||||||
|
return x - (int)(x / m) * m;
|
||||||
|
};
|
||||||
|
|
||||||
return modf(time - offset, ((double)interval) * 2) >= interval;
|
return modf(time - offset, ((double)interval) * 2) >= interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,3 +54,23 @@ bool Time::between_interval(float interval, float offset)
|
||||||
{
|
{
|
||||||
return between_interval(Time::seconds, interval, offset);
|
return between_interval(Time::seconds, interval, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stopwatch::Stopwatch()
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stopwatch::reset()
|
||||||
|
{
|
||||||
|
start_time = std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 Stopwatch::milliseconds()
|
||||||
|
{
|
||||||
|
return microseconds() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 Stopwatch::microseconds()
|
||||||
|
{
|
||||||
|
return std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count() - start_time;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user