# Changes
3ds Backend: - switch to shaderProgramUse Desktop Backend - Add Pre Alpha Text Input and Keyboard Support - Move Shader Attrib Setup into a function and callit every time we need a set up vbo - Move to Mat4 api Core: - Add fquat support - Add LoadFile2Str - Move Mat4 Lib from Project n73 to Palladium - Add full supprot for vec cross types - Add Normalize, Distance and Dot to all - Add Cross to vec3 Drivers: - Add a SetViewPort func to GFX - Add Keyboard keys and Flasg to Hid Image: - Add Vertical Flipping - Add Horizontal flipping UI7: - Fix Critical Bug in IO Viewport handler - Fix library list (error on MinGW for some reason) Lazyvec: - Split into multiple source files - Generate new functions (see core updates)
This commit is contained in:
@ -130,11 +130,14 @@ void GfxC3D::BindTex(PD::Li::TexAddress addr) {
|
||||
}
|
||||
|
||||
void GfxC3D::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
||||
C3D_BindProgram(&Shader);
|
||||
// C3D_BindProgram(&Shader);
|
||||
shaderProgramUse(&Shader);
|
||||
C3D_SetAttrInfo(&ShaderInfo);
|
||||
C3D_Mtx proj;
|
||||
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, &proj);
|
||||
// Mat4 proj = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f);
|
||||
// C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, pLocProjection, (C3D_Mtx*)&proj);
|
||||
C3D_DepthTest(false, GPU_GREATER, GPU_WRITE_ALL);
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvInit(env);
|
||||
|
@ -37,9 +37,36 @@ class HidGLFW : public HidDriver {
|
||||
PD_SHARED(HidGLFW);
|
||||
|
||||
void Update() override;
|
||||
void GetInputStr(std::string& str) override;
|
||||
void HandleTextOps();
|
||||
bool pTimedHeld(KbKey k) {
|
||||
if (pTimings.count(k)) {
|
||||
if (IsEvent(Event_Up, k)) {
|
||||
pTimings.erase(k);
|
||||
return false;
|
||||
}
|
||||
return (PD::OS::GetTime() - pTimings[k]) > 50;
|
||||
}
|
||||
if (!IsEvent(Event_Held, k)) {
|
||||
if (pTimings.count(k)) {
|
||||
pTimings.erase(k);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (IsEvent(Event_Held, k)) {
|
||||
pTimings[k] = PD::OS::GetTime();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Data section */
|
||||
GLFWwindow* Window;
|
||||
int PrevState;
|
||||
std::unordered_map<int, int> PrevStates;
|
||||
static std::string* pText;
|
||||
bool pInTextMode = false;
|
||||
PD::u64 pLastUpdate = 0;
|
||||
std::unordered_map<KbKey, u64> pTimings;
|
||||
};
|
||||
} // namespace PD
|
@ -36,7 +36,7 @@ const char* vertex_shader = R"(
|
||||
varying vec2 oUV;
|
||||
varying vec4 oColor;
|
||||
|
||||
// Probably forgot about this matric and
|
||||
// Probably forgot about this matrix and
|
||||
// searched hours for why the rendering isn't working :/
|
||||
uniform mat4 projection;
|
||||
|
||||
@ -103,17 +103,7 @@ GLuint createShaderProgram(const std::string& vertexShaderSource,
|
||||
return shaderProgram;
|
||||
}
|
||||
|
||||
/** Actual Backend */
|
||||
|
||||
void GfxGL2::Init() {
|
||||
VertexBuffer.Resize(4 * 8192);
|
||||
IndexBuffer.Resize(6 * 8192);
|
||||
Shader = createShaderProgram(vertex_shader, frag_shader);
|
||||
glUseProgram(Shader);
|
||||
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
void SetupShaderAttribs(GLuint Shader) {
|
||||
GLint _pos = glGetAttribLocation(Shader, "pos");
|
||||
GLint _uv = glGetAttribLocation(Shader, "uv");
|
||||
GLint _color = glGetAttribLocation(Shader, "color");
|
||||
@ -129,6 +119,21 @@ void GfxGL2::Init() {
|
||||
sizeof(PD::Li::Vertex),
|
||||
(void*)offsetof(PD::Li::Vertex, Color));
|
||||
glEnableVertexAttribArray(_color);
|
||||
}
|
||||
|
||||
/** Actual Backend */
|
||||
|
||||
void GfxGL2::Init() {
|
||||
VertexBuffer.Resize(4 * 8192);
|
||||
IndexBuffer.Resize(6 * 8192);
|
||||
Shader = createShaderProgram(vertex_shader, frag_shader);
|
||||
glUseProgram(Shader);
|
||||
|
||||
glGenBuffers(1, &VBO);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
|
||||
// Attribs Setup
|
||||
SetupShaderAttribs(Shader);
|
||||
|
||||
glGenBuffers(1, &IBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||
@ -146,11 +151,14 @@ void GfxGL2::Deinit() {
|
||||
}
|
||||
|
||||
void GfxGL2::NewFrame() {
|
||||
/*
|
||||
glViewport(0, 0, ViewPort.x, ViewPort.y);
|
||||
glClearColor(ClearColor.x, ClearColor.y, ClearColor.z, ClearColor.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
Projection.Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, -1.f, 1.f);
|
||||
glUniformMatrix4fv(pLocProjection, 1, GL_TRUE, Projection.m);
|
||||
*/
|
||||
Projection = Mat4::Ortho(0.f, ViewPort.x, ViewPort.y, 0.f, -1.f, 1.f);
|
||||
glUseProgram(Shader);
|
||||
glUniformMatrix4fv(pLocProjection, 1, GL_FALSE, Projection.m.data());
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
CurrentIndex = 0;
|
||||
@ -170,7 +178,6 @@ void GfxGL2::BindTex(PD::Li::TexAddress addr) {
|
||||
}
|
||||
|
||||
void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
||||
glUseProgram(Shader);
|
||||
size_t index = 0;
|
||||
while (index < Commands.size()) {
|
||||
PD::Li::Texture::Ref Tex = Commands[index]->Tex;
|
||||
@ -207,6 +214,9 @@ void GfxGL2::RenderDrawData(const std::vector<PD::Li::Command::Ref>& Commands) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, CurrentVertex * sizeof(PD::Li::Vertex),
|
||||
&VertexBuffer[0], GL_DYNAMIC_DRAW);
|
||||
// For some reason we need to set these every frame for every buffer
|
||||
// Found that out when creating My 3d Engine
|
||||
SetupShaderAttribs(Shader);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, CurrentIndex * sizeof(PD::u16),
|
||||
|
@ -23,19 +23,104 @@ SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <pd-desktop/bknd-hid.hpp>
|
||||
|
||||
namespace PD {
|
||||
std::string* HidGLFW::pText;
|
||||
// Default Call back (If no Text input is requsted)
|
||||
void NullTextCB(GLFWwindow* win, unsigned int c) {}
|
||||
// Text callback if requested
|
||||
void TextCB(GLFWwindow* win, unsigned int c) {
|
||||
if (!HidGLFW::pText) {
|
||||
return;
|
||||
}
|
||||
*HidGLFW::pText += (char)c;
|
||||
}
|
||||
HidGLFW::HidGLFW(GLFWwindow* win) : HidDriver("HidGLFW") {
|
||||
Window = win;
|
||||
glfwSetCharCallback(Window, NullTextCB);
|
||||
Flags |= Flags_HasKeyboard;
|
||||
Flags |= Flags_HasMouse;
|
||||
pBinds[GLFW_MOUSE_BUTTON_LEFT] = Touch;
|
||||
pBinds[GLFW_KEY_F3] = Kb_3;
|
||||
pBinds[GLFW_KEY_ESCAPE] = Kb_Escape;
|
||||
pBinds[GLFW_KEY_F11] = Kb_F11;
|
||||
pBinds[GLFW_KEY_ESCAPE] = Kb_Escape;
|
||||
pBinds[GLFW_KEY_Q] = Kb_Q;
|
||||
pBinds[GLFW_KEY_W] = Kb_W;
|
||||
pBinds[GLFW_KEY_E] = Kb_E;
|
||||
pBinds[GLFW_KEY_R] = Kb_R;
|
||||
pBinds[GLFW_KEY_T] = Kb_T;
|
||||
pBinds[GLFW_KEY_Z] = Kb_Z;
|
||||
pBinds[GLFW_KEY_U] = Kb_U;
|
||||
pBinds[GLFW_KEY_I] = Kb_I;
|
||||
pBinds[GLFW_KEY_O] = Kb_O;
|
||||
pBinds[GLFW_KEY_P] = Kb_P;
|
||||
pBinds[GLFW_KEY_A] = Kb_A;
|
||||
pBinds[GLFW_KEY_S] = Kb_S;
|
||||
pBinds[GLFW_KEY_D] = Kb_D;
|
||||
pBinds[GLFW_KEY_F] = Kb_F;
|
||||
pBinds[GLFW_KEY_G] = Kb_G;
|
||||
pBinds[GLFW_KEY_H] = Kb_H;
|
||||
pBinds[GLFW_KEY_J] = Kb_J;
|
||||
pBinds[GLFW_KEY_K] = Kb_K;
|
||||
pBinds[GLFW_KEY_L] = Kb_L;
|
||||
pBinds[GLFW_KEY_Y] = Kb_Y;
|
||||
pBinds[GLFW_KEY_X] = Kb_X;
|
||||
pBinds[GLFW_KEY_C] = Kb_C;
|
||||
pBinds[GLFW_KEY_V] = Kb_V;
|
||||
pBinds[GLFW_KEY_B] = Kb_B;
|
||||
pBinds[GLFW_KEY_N] = Kb_N;
|
||||
pBinds[GLFW_KEY_M] = Kb_M;
|
||||
pBinds[GLFW_KEY_LEFT_SHIFT] = Kb_LShift;
|
||||
pBinds[GLFW_KEY_F1] = Kb_F1;
|
||||
pBinds[GLFW_KEY_F2] = Kb_F2;
|
||||
pBinds[GLFW_KEY_F3] = Kb_F3;
|
||||
pBinds[GLFW_KEY_F4] = Kb_F4;
|
||||
pBinds[GLFW_KEY_F5] = Kb_F5;
|
||||
pBinds[GLFW_KEY_F6] = Kb_F6;
|
||||
pBinds[GLFW_KEY_F7] = Kb_F7;
|
||||
pBinds[GLFW_KEY_F8] = Kb_F8;
|
||||
pBinds[GLFW_KEY_F9] = Kb_F9;
|
||||
pBinds[GLFW_KEY_F10] = Kb_F10;
|
||||
pBinds[GLFW_KEY_F11] = Kb_F11;
|
||||
pBinds[GLFW_KEY_F12] = Kb_F12;
|
||||
pBinds[GLFW_KEY_1] = Kb_1;
|
||||
pBinds[GLFW_KEY_2] = Kb_2;
|
||||
pBinds[GLFW_KEY_3] = Kb_3;
|
||||
pBinds[GLFW_KEY_4] = Kb_4;
|
||||
pBinds[GLFW_KEY_5] = Kb_5;
|
||||
pBinds[GLFW_KEY_6] = Kb_6;
|
||||
pBinds[GLFW_KEY_7] = Kb_7;
|
||||
pBinds[GLFW_KEY_8] = Kb_8;
|
||||
pBinds[GLFW_KEY_9] = Kb_9;
|
||||
pBinds[GLFW_KEY_0] = Kb_0;
|
||||
pBinds[GLFW_KEY_BACKSPACE] = Kb_Backspace;
|
||||
pBinds[GLFW_KEY_ENTER] = Kb_Enter;
|
||||
}
|
||||
|
||||
void HidGLFW::Update() {
|
||||
// Clear States
|
||||
for (int i = 0; i < 2; i++) {
|
||||
KeyEvents[i][Event_Down] = 0;
|
||||
KeyEvents[i][Event_Held] = 0;
|
||||
KeyEvents[i][Event_Up] = 0;
|
||||
for (auto& it : KbKeyEvents[i]) {
|
||||
it.second = Event_Null;
|
||||
}
|
||||
}
|
||||
// Keyboard Logic
|
||||
for (auto& it : pBinds) {
|
||||
int kbstate = glfwGetKey(Window, it.first);
|
||||
if (kbstate == GLFW_PRESS) {
|
||||
if (PrevStates[it.first] == GLFW_RELEASE) {
|
||||
KbKeyEvents[0][it.second] = Event_Down;
|
||||
}
|
||||
KbKeyEvents[0][it.second] = Event_Held;
|
||||
} else if (kbstate == GLFW_RELEASE && PrevStates[it.first] == GLFW_PRESS) {
|
||||
KbKeyEvents[0][it.second] = Event_Up;
|
||||
}
|
||||
PrevStates[it.first] = kbstate;
|
||||
}
|
||||
// Mouse Logic (Todo: Support all mouse buttons)
|
||||
int state = glfwGetMouseButton(Window, GLFW_MOUSE_BUTTON_LEFT);
|
||||
if (state == GLFW_PRESS) {
|
||||
if (PrevState == GLFW_RELEASE) {
|
||||
@ -54,5 +139,28 @@ void HidGLFW::Update() {
|
||||
glfwGetCursorPos(Window, &x, &y);
|
||||
pMouse[1] = pMouse[0]; // Cycle pMouse pos
|
||||
pMouse[0] = fvec2(x, y);
|
||||
if (pInTextMode && (PD::OS::GetTime() - pLastUpdate) > 50) {
|
||||
pLastUpdate = PD::OS::GetTime();
|
||||
HandleTextOps();
|
||||
}
|
||||
}
|
||||
|
||||
void HidGLFW::GetInputStr(std::string& str) {
|
||||
pText = &str;
|
||||
glfwSetCharCallback(Window, TextCB);
|
||||
pInTextMode = true;
|
||||
}
|
||||
|
||||
void HidGLFW::HandleTextOps() {
|
||||
if (!pText) {
|
||||
return;
|
||||
}
|
||||
if (pTimedHeld(Kb_Backspace)) {
|
||||
if (!pText->empty()) {
|
||||
pText->pop_back();
|
||||
}
|
||||
} else if (pTimedHeld(Kb_Enter)) {
|
||||
*pText += '\n';
|
||||
}
|
||||
}
|
||||
} // namespace PD
|
@ -23,6 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
@ -33,6 +34,7 @@ SOFTWARE.
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <numbers>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
55
include/pd/core/fquat.hpp
Normal file
55
include/pd/core/fquat.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is based on fvec4
|
||||
|
||||
#include <pd/core/common.hpp>
|
||||
#include <pd/core/vec4.hpp>
|
||||
|
||||
namespace PD {
|
||||
class fquat : public fvec4 {
|
||||
constexpr fquat() : fvec4(0.f, 0.f, 0.f, 1.f) {}
|
||||
constexpr fquat(float x, float y, float z, float w) : fvec4(x, y, z, w) {}
|
||||
constexpr fquat(const fvec4& v) : fvec4(v) {}
|
||||
|
||||
static fquat Identity() { return fquat(0.f, 0.f, 0.f, 1.f); }
|
||||
|
||||
constexpr fquat Conjugate() const { return fquat(-x, -y, -z, w); }
|
||||
fquat Inverse() const {
|
||||
float len = SqLen();
|
||||
if (len == 0.0f) {
|
||||
return fquat();
|
||||
}
|
||||
return Conjugate() / len;
|
||||
}
|
||||
|
||||
fquat operator*(const fquat& v) const {
|
||||
return fquat(w * v.x + x * v.w + y * v.z - z * v.y,
|
||||
w * v.y - x * v.z + y * v.w + z * v.x,
|
||||
w * v.z + x * v.y - y * v.x + z * v.w,
|
||||
w * v.w - x * v.x - y * v.y - z * v.z);
|
||||
}
|
||||
};
|
||||
} // namespace PD
|
@ -36,6 +36,12 @@ namespace IO {
|
||||
* @return 8Bit FileBuffer
|
||||
*/
|
||||
PD_CORE_API std::vector<u8> LoadFile2Mem(const std::string& path);
|
||||
/**
|
||||
* Load a File into a std::string
|
||||
* @param path Path to the File
|
||||
* @return std::string file content
|
||||
*/
|
||||
PD_CORE_API std::string LoadFile2Str(const std::string& path);
|
||||
/**
|
||||
* Hash a 8Bit Memory Buffer
|
||||
* @param data 8Bit input Buffer
|
||||
|
@ -25,17 +25,118 @@ SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <pd/core/common.hpp>
|
||||
#include <pd/core/vec3.hpp>
|
||||
|
||||
namespace PD {
|
||||
class PD_CORE_API Mat4 {
|
||||
public:
|
||||
Mat4() { Zeros(); }
|
||||
~Mat4() = default;
|
||||
namespace Numbers {
|
||||
constexpr float Tau = std::numbers::pi * 2.f;
|
||||
}
|
||||
constexpr float Radians(float v) { return v * (Numbers::Tau / 360.0f); }
|
||||
/**
|
||||
* Minimal Mtx4 Lib that precomputes
|
||||
* basic stuff stuff at compiletime
|
||||
*
|
||||
* This Lib includes Patches for work with Citro3D as well
|
||||
*
|
||||
* @note That this is not a full Matrix Library
|
||||
*/
|
||||
|
||||
void Zeros();
|
||||
void Ortho(float left, float right, float bottom, float top, float near,
|
||||
float far);
|
||||
struct PD_CORE_API Mat4 {
|
||||
std::array<float, 16> m;
|
||||
constexpr Mat4() : m{} {}
|
||||
constexpr static Mat4 Diagonal(float x, float y, float z, float w) {
|
||||
Mat4 ret;
|
||||
ret(0, 0) = x;
|
||||
ret(1, 1) = y;
|
||||
ret(2, 2) = z;
|
||||
ret(3, 3) = w;
|
||||
return ret;
|
||||
}
|
||||
constexpr static Mat4 Identity() { return Diagonal(1, 1, 1, 1); }
|
||||
|
||||
float m[16];
|
||||
constexpr float* Ptr() { return m.data(); }
|
||||
constexpr const float* Ptr() const { return m.data(); }
|
||||
|
||||
constexpr float& operator()(int row, int col) {
|
||||
#ifdef __3DS__
|
||||
// 3ds is full reverse order iirc
|
||||
return m[row * 4 + (3 - col)];
|
||||
#else
|
||||
return m[col * 4 + row];
|
||||
#endif
|
||||
}
|
||||
constexpr float operator()(int row, int col) const {
|
||||
#ifdef __3DS__
|
||||
// 3ds is full reverse order iirc
|
||||
return m[row * 4 + (3 - col)];
|
||||
#else
|
||||
return m[col * 4 + row];
|
||||
#endif
|
||||
}
|
||||
|
||||
constexpr Mat4 operator*(const Mat4& v) const {
|
||||
Mat4 ret;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
float t = 0.f;
|
||||
for (int k = 0; k < 4; k++) {
|
||||
t += (*this)(i, k) * v(k, j);
|
||||
}
|
||||
ret(i, j) = t;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
constexpr Mat4& operator*=(const Mat4& v) {
|
||||
*this = *this * v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr static Mat4 Translate(float x, float y, float z) {
|
||||
Mat4 ret = Identity();
|
||||
ret(0, 3) = x;
|
||||
ret(1, 3) = y;
|
||||
ret(2, 3) = z;
|
||||
return ret;
|
||||
}
|
||||
|
||||
constexpr static Mat4 Scale(float x, float y, float z) {
|
||||
Mat4 ret;
|
||||
ret(0, 0) = x;
|
||||
ret(1, 1) = y;
|
||||
ret(2, 2) = z;
|
||||
ret(3, 3) = 1.f;
|
||||
return ret;
|
||||
}
|
||||
|
||||
constexpr static Mat4 Ortho(float l, float r, float b, float t, float n,
|
||||
float f) {
|
||||
Mat4 ret;
|
||||
#ifdef __3DS__ // Patch to rotate the Matrix correctly
|
||||
ret(0, 1) = 2.f / (t - b);
|
||||
ret(0, 3) = (b + t) / (b - t);
|
||||
ret(1, 0) = 2.f / (l - r);
|
||||
ret(1, 3) = (l + r) / (r - l);
|
||||
ret(2, 2) = 1.f / (n - f);
|
||||
ret(2, 3) = 0.5f * (n + f) / (n - f) - 0.5f;
|
||||
#else
|
||||
ret(0, 0) = 2.0f / (r - l);
|
||||
ret(0, 3) = -(r + l) / (r - l);
|
||||
ret(1, 1) = 2.0f / (t - b);
|
||||
ret(1, 3) = -(t + b) / (t - b);
|
||||
ret(2, 2) = -2.0f / (f - n);
|
||||
ret(2, 3) = -(f + n) / (f - n);
|
||||
#endif
|
||||
ret(3, 3) = 1.f;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Mat4 Rotate(fvec3 axis, float a);
|
||||
static Mat4 RotateX(float a);
|
||||
static Mat4 RotateY(float a);
|
||||
static Mat4 RotateZ(float a);
|
||||
static Mat4 Perspective(float fov, float aspect, float n, float f);
|
||||
static Mat4 LookAt(const fvec3& pos, const fvec3& center, const fvec3& up);
|
||||
};
|
||||
} // namespace PD
|
@ -23,7 +23,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is generated by lazyvec
|
||||
// This file is generated by lazyvec 2.0.0
|
||||
|
||||
#include <pd/core/common.hpp>
|
||||
|
||||
namespace PD {
|
||||
@ -33,20 +34,24 @@ class vec2 {
|
||||
T x;
|
||||
T y;
|
||||
|
||||
vec2() : x(0), y(0) {}
|
||||
// Constructors
|
||||
|
||||
constexpr vec2() : x(0), y(0) {}
|
||||
template <typename T1>
|
||||
vec2(T1 v) {
|
||||
constexpr vec2(T1 v) {
|
||||
x = (T)v;
|
||||
y = (T)v;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
vec2(vec2<T1> v) {
|
||||
constexpr vec2(const vec2<T1>& v) {
|
||||
x = (T)v.x;
|
||||
y = (T)v.y;
|
||||
}
|
||||
|
||||
vec2(T x, T y) : x(x), y(y) {}
|
||||
constexpr explicit vec2(T x, T y) : x(x), y(y) {}
|
||||
|
||||
// Operations
|
||||
|
||||
template <typename T1>
|
||||
vec2<T>& operator+=(T1 v) {
|
||||
@ -144,14 +149,42 @@ class vec2 {
|
||||
return vec2<T>(x / (T)v.x, y / (T)v.y);
|
||||
}
|
||||
|
||||
vec2 operator-() const { return vec2(-x, -y); }
|
||||
// Generic Operations
|
||||
|
||||
bool operator==(const vec2& v) const { return x == v.x && y == v.y; }
|
||||
bool operator!=(const vec2& v) const { return !(*this == v); }
|
||||
vec2 operator-() const { return vec2(-x, -y); }
|
||||
template <typename T1>
|
||||
bool operator==(const vec2<T1>& v) const {
|
||||
return x == (T)v.x && y == (T)v.y;
|
||||
}
|
||||
template <typename T1>
|
||||
bool operator!=(const vec2<T1>& v) const {
|
||||
return !(*this == v);
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
||||
double Len() const { return std::sqrt(SqLen()); }
|
||||
double SqLen() const { return x * x + y * y; }
|
||||
|
||||
template <typename T1>
|
||||
double Distance(const vec2<T1>& v) const {
|
||||
return (*this - v).Len();
|
||||
}
|
||||
|
||||
vec2<T> Normalize() const {
|
||||
double l = Len();
|
||||
if (l == 0) {
|
||||
return *this;
|
||||
}
|
||||
return *this / (T)l;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
T Dot(const vec2<T1>& v) const {
|
||||
return x * (T)v.x + y * (T)v.y;
|
||||
}
|
||||
|
||||
// Swap Functions
|
||||
void SwapXY() {
|
||||
T t = x;
|
||||
x = y;
|
||||
@ -159,6 +192,6 @@ class vec2 {
|
||||
}
|
||||
};
|
||||
using fvec2 = vec2<float>;
|
||||
using dvec2 = vec2<double>;
|
||||
using ivec2 = vec2<int>;
|
||||
using dvec2 = vec2<double>;
|
||||
} // namespace PD
|
||||
|
@ -23,8 +23,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is generated by lazyvec
|
||||
// This file is generated by lazyvec 2.0.0
|
||||
|
||||
#include <pd/core/common.hpp>
|
||||
// Extended includes (rename if you use other filenames/paths)
|
||||
#include <pd/core/vec2.hpp>
|
||||
|
||||
namespace PD {
|
||||
template <typename T>
|
||||
@ -34,22 +37,36 @@ class vec3 {
|
||||
T y;
|
||||
T z;
|
||||
|
||||
vec3() : x(0), y(0), z(0) {}
|
||||
// Constructors
|
||||
|
||||
constexpr vec3() : x(0), y(0), z(0) {}
|
||||
template <typename T1>
|
||||
explicit vec3(T1 v) {
|
||||
constexpr vec3(T1 v) {
|
||||
x = (T)v;
|
||||
y = (T)v;
|
||||
z = (T)v;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
explicit vec3(vec3<T1> v) {
|
||||
constexpr vec3(const vec3<T1>& v) {
|
||||
x = (T)v.x;
|
||||
y = (T)v.y;
|
||||
z = (T)v.z;
|
||||
}
|
||||
|
||||
vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||
constexpr explicit vec3(T x, T y, T z) : x(x), y(y), z(z) {}
|
||||
|
||||
// Extended Constructors
|
||||
template <typename T1>
|
||||
constexpr explicit vec3(const vec2<T1>& xy, T1 z) {
|
||||
{
|
||||
x = (T)xy.x;
|
||||
y = (T)xy.y;
|
||||
this->z = (T)z;
|
||||
}
|
||||
}
|
||||
|
||||
// Operations
|
||||
|
||||
template <typename T1>
|
||||
vec3<T>& operator+=(T1 v) {
|
||||
@ -155,16 +172,47 @@ class vec3 {
|
||||
return vec3<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z);
|
||||
}
|
||||
|
||||
vec3 operator-() const { return vec3(-x, -y, -z); }
|
||||
// Generic Operations
|
||||
|
||||
bool operator==(const vec3& v) const {
|
||||
return x == v.x && y == v.y && z == v.z;
|
||||
vec3 operator-() const { return vec3(-x, -y, -z); }
|
||||
template <typename T1>
|
||||
bool operator==(const vec3<T1>& v) const {
|
||||
return x == (T)v.x && y == (T)v.y && z == (T)v.z;
|
||||
}
|
||||
bool operator!=(const vec3& v) const { return !(*this == v); }
|
||||
template <typename T1>
|
||||
bool operator!=(const vec3<T1>& v) const {
|
||||
return !(*this == v);
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
||||
double Len() const { return std::sqrt(SqLen()); }
|
||||
double SqLen() const { return x * x + y * y + z * z; }
|
||||
|
||||
template <typename T1>
|
||||
double Distance(const vec3<T1>& v) const {
|
||||
return (*this - v).Len();
|
||||
}
|
||||
|
||||
vec3<T> Normalize() const {
|
||||
double l = Len();
|
||||
if (l == 0) {
|
||||
return *this;
|
||||
}
|
||||
return *this / (T)l;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
T Dot(const vec3<T1>& v) const {
|
||||
return x * (T)v.x + y * (T)v.y + z * (T)v.z;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
vec3<T> Cross(const vec3<T1>& v) const {
|
||||
return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||||
}
|
||||
|
||||
// Swap Functions
|
||||
void SwapXY() {
|
||||
T t = x;
|
||||
x = y;
|
||||
@ -182,6 +230,6 @@ class vec3 {
|
||||
}
|
||||
};
|
||||
using fvec3 = vec3<float>;
|
||||
using dvec3 = vec3<double>;
|
||||
using ivec3 = vec3<int>;
|
||||
using dvec3 = vec3<double>;
|
||||
} // namespace PD
|
||||
|
@ -23,9 +23,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is generated by lazyvec
|
||||
// This file is generated by lazyvec 2.0.0
|
||||
|
||||
#include <pd/core/common.hpp>
|
||||
#include <pd/core/vec2.hpp> // Extended
|
||||
// Extended includes (rename if you use other filenames/paths)
|
||||
#include <pd/core/vec2.hpp>
|
||||
#include <pd/core/vec3.hpp>
|
||||
|
||||
namespace PD {
|
||||
template <typename T>
|
||||
@ -36,9 +39,11 @@ class vec4 {
|
||||
T z;
|
||||
T w;
|
||||
|
||||
vec4() : x(0), y(0), z(0), w(0) {}
|
||||
// Constructors
|
||||
|
||||
constexpr vec4() : x(0), y(0), z(0), w(0) {}
|
||||
template <typename T1>
|
||||
explicit vec4(T1 v) {
|
||||
constexpr vec4(T1 v) {
|
||||
x = (T)v;
|
||||
y = (T)v;
|
||||
z = (T)v;
|
||||
@ -46,23 +51,37 @@ class vec4 {
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
explicit vec4(vec4<T1> v) {
|
||||
constexpr vec4(const vec4<T1>& v) {
|
||||
x = (T)v.x;
|
||||
y = (T)v.y;
|
||||
z = (T)v.z;
|
||||
w = (T)v.w;
|
||||
}
|
||||
|
||||
/** Extended Constructor */
|
||||
constexpr explicit vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
|
||||
|
||||
// Extended Constructors
|
||||
template <typename T1>
|
||||
explicit vec4(vec2<T1> a, vec2<T1> b) {
|
||||
x = (T)a.x;
|
||||
y = (T)a.y;
|
||||
z = (T)b.x;
|
||||
w = (T)b.y;
|
||||
constexpr explicit vec4(const vec2<T1>& xy, const vec2<T1>& zw) {
|
||||
{
|
||||
x = (T)xy.x;
|
||||
y = (T)xy.y;
|
||||
z = (T)zw.x;
|
||||
w = (T)zw.y;
|
||||
}
|
||||
}
|
||||
|
||||
vec4(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
|
||||
template <typename T1>
|
||||
constexpr explicit vec4(const vec3<T1>& xyz, T1 w) {
|
||||
{
|
||||
x = (T)xyz.x;
|
||||
y = (T)xyz.y;
|
||||
z = (T)xyz.z;
|
||||
this->w = (T)w;
|
||||
}
|
||||
}
|
||||
|
||||
// Operations
|
||||
|
||||
template <typename T1>
|
||||
vec4<T>& operator+=(T1 v) {
|
||||
@ -176,16 +195,42 @@ class vec4 {
|
||||
return vec4<T>(x / (T)v.x, y / (T)v.y, z / (T)v.z, w / (T)v.w);
|
||||
}
|
||||
|
||||
vec4 operator-() const { return vec4(-x, -y, -z, -w); }
|
||||
// Generic Operations
|
||||
|
||||
bool operator==(const vec4& v) const {
|
||||
return x == v.x && y == v.y && z == v.z && w == v.w;
|
||||
vec4 operator-() const { return vec4(-x, -y, -z, -w); }
|
||||
template <typename T1>
|
||||
bool operator==(const vec4<T1>& v) const {
|
||||
return x == (T)v.x && y == (T)v.y && z == (T)v.z && w == (T)v.w;
|
||||
}
|
||||
bool operator!=(const vec4& v) const { return !(*this == v); }
|
||||
template <typename T1>
|
||||
bool operator!=(const vec4<T1>& v) const {
|
||||
return !(*this == v);
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
||||
double Len() const { return std::sqrt(SqLen()); }
|
||||
double SqLen() const { return x * x + y * y + z * z + w * w; }
|
||||
|
||||
template <typename T1>
|
||||
double Distance(const vec4<T1>& v) const {
|
||||
return (*this - v).Len();
|
||||
}
|
||||
|
||||
vec4<T> Normalize() const {
|
||||
double l = Len();
|
||||
if (l == 0) {
|
||||
return *this;
|
||||
}
|
||||
return *this / (T)l;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
T Dot(const vec4<T1>& v) const {
|
||||
return x * (T)v.x + y * (T)v.y + z * (T)v.z + w * (T)v.w;
|
||||
}
|
||||
|
||||
// Swap Functions
|
||||
void SwapXY() {
|
||||
T t = x;
|
||||
x = y;
|
||||
@ -218,6 +263,6 @@ class vec4 {
|
||||
}
|
||||
};
|
||||
using fvec4 = vec4<float>;
|
||||
using dvec4 = vec4<double>;
|
||||
using ivec4 = vec4<int>;
|
||||
using dvec4 = vec4<double>;
|
||||
} // namespace PD
|
||||
|
@ -52,6 +52,8 @@ class GfxDriver {
|
||||
|
||||
virtual void RenderDrawData(const std::vector<Command::Ref>& Commands) {}
|
||||
|
||||
void SetViewPort(const ivec2& vp) { ViewPort = vp; }
|
||||
|
||||
virtual Texture::Ref LoadTex(
|
||||
const std::vector<u8>& pixels, int w, int h,
|
||||
Texture::Type type = Texture::Type::RGBA32,
|
||||
@ -90,6 +92,7 @@ class Gfx {
|
||||
static void NewFrame() { pGfx->NewFrame(); }
|
||||
|
||||
static void BindTex(TexAddress addr) { pGfx->BindTex(addr); }
|
||||
static void SetViewPort(const ivec2& vp) { pGfx->SetViewPort(vp); }
|
||||
|
||||
static void RenderDrawData(const std::vector<Command::Ref>& Commands) {
|
||||
pGfx->RenderDrawData(Commands);
|
||||
|
@ -28,6 +28,14 @@ SOFTWARE.
|
||||
namespace PD {
|
||||
class HidDriver {
|
||||
public:
|
||||
enum Flags : u32 {
|
||||
Flags_None,
|
||||
FLags_HasGamepad,
|
||||
Flags_HasKeyboard,
|
||||
Flags_HasTouch,
|
||||
Flags_HasMouse,
|
||||
};
|
||||
// Todo: Name to GpKey (GamepadKey)
|
||||
/** Key [Controller] */
|
||||
enum Key : u32 {
|
||||
No = 0, ///< No Key
|
||||
@ -60,8 +68,68 @@ class HidDriver {
|
||||
Right = DRight | CPRight, ///< DPad or CPad Right
|
||||
};
|
||||
|
||||
// Dont want to use some hardcoded bitset
|
||||
// so lets use just numbers
|
||||
enum KbKey : u8 {
|
||||
Kb_No = 0,
|
||||
Kb_Escape = 1,
|
||||
Kb_Q = 2,
|
||||
Kb_W = 3,
|
||||
Kb_E = 4,
|
||||
Kb_R = 5,
|
||||
Kb_T = 6,
|
||||
// Yes i use QWERTZ Keyboard
|
||||
Kb_Z = 7,
|
||||
Kb_U = 8,
|
||||
Kb_I = 9,
|
||||
Kb_O = 10,
|
||||
Kb_P = 11,
|
||||
Kb_A = 12,
|
||||
Kb_S = 13,
|
||||
Kb_D = 14,
|
||||
Kb_F = 15,
|
||||
Kb_G = 16,
|
||||
Kb_H = 17,
|
||||
Kb_J = 18,
|
||||
Kb_K = 19,
|
||||
Kb_L = 20,
|
||||
Kb_Y = 21,
|
||||
Kb_X = 22,
|
||||
Kb_C = 23,
|
||||
Kb_V = 24,
|
||||
Kb_B = 25,
|
||||
Kb_N = 26,
|
||||
Kb_M = 27,
|
||||
Kb_LShift = 28,
|
||||
Kb_F1 = 29,
|
||||
Kb_F2 = 30,
|
||||
Kb_F3 = 31,
|
||||
Kb_F4 = 32,
|
||||
Kb_F5 = 33,
|
||||
Kb_F6 = 34,
|
||||
Kb_F7 = 35,
|
||||
Kb_F8 = 36,
|
||||
Kb_F9 = 37,
|
||||
Kb_F10 = 38,
|
||||
Kb_F11 = 39,
|
||||
Kb_F12 = 40,
|
||||
Kb_1 = 41,
|
||||
Kb_2 = 42,
|
||||
Kb_3 = 43,
|
||||
Kb_4 = 44,
|
||||
Kb_5 = 45,
|
||||
Kb_6 = 46,
|
||||
Kb_7 = 47,
|
||||
Kb_8 = 48,
|
||||
Kb_9 = 49,
|
||||
Kb_0 = 50,
|
||||
Kb_Backspace = 51,
|
||||
Kb_Enter = 52,
|
||||
};
|
||||
|
||||
/** Event */
|
||||
enum Event {
|
||||
Event_Null,
|
||||
Event_Down, ///< Key Pressed
|
||||
Event_Held, ///< Key Held
|
||||
Event_Up, ///< Key released
|
||||
@ -90,6 +158,7 @@ class HidDriver {
|
||||
* @return if key(s) doing the requiested event
|
||||
*/
|
||||
bool IsEvent(Event e, Key keys);
|
||||
bool IsEvent(Event e, KbKey key);
|
||||
/**
|
||||
* Check for Key Press Event
|
||||
* @param keys set of keys
|
||||
@ -160,12 +229,19 @@ class HidDriver {
|
||||
* Template Update Function for a device specific driver
|
||||
*/
|
||||
virtual void Update() {}
|
||||
/**
|
||||
* Get Text from Keyboard
|
||||
*/
|
||||
virtual void GetInputStr(std::string& str) {}
|
||||
|
||||
/** Data Section */
|
||||
|
||||
/** Backend Identification Name */
|
||||
const std::string pName;
|
||||
|
||||
/** Flags */
|
||||
u32 Flags = 0;
|
||||
|
||||
/** Key Binds Map */
|
||||
std::unordered_map<u32, u32> pBinds;
|
||||
/** Swap Tabe Function */
|
||||
@ -176,6 +252,8 @@ class HidDriver {
|
||||
bool pLocked = false;
|
||||
/** Key Event Table Setup */
|
||||
std::unordered_map<Event, u32> KeyEvents[2];
|
||||
/** Keyboard Key Event Table Setup */
|
||||
std::unordered_map<u32, Event> KbKeyEvents[2];
|
||||
};
|
||||
|
||||
/** Static Hid Controller */
|
||||
@ -186,6 +264,7 @@ class Hid {
|
||||
|
||||
/** Referenec to Drivers enums */
|
||||
using Key = HidDriver::Key;
|
||||
using KbKey = HidDriver::KbKey;
|
||||
using Event = HidDriver::Event;
|
||||
|
||||
static void Init(HidDriver::Ref v = nullptr) {
|
||||
@ -197,6 +276,7 @@ class Hid {
|
||||
}
|
||||
|
||||
static bool IsEvent(Event e, Key keys) { return pHid->IsEvent(e, keys); }
|
||||
static bool IsEvent(Event e, KbKey key) { return pHid->IsEvent(e, key); }
|
||||
static bool IsDown(Key keys) { return pHid->IsDown(keys); }
|
||||
static bool IsUp(Key keys) { return pHid->IsUp(keys); }
|
||||
static bool IsHeld(Key keys) { return pHid->IsHeld(keys); }
|
||||
@ -208,6 +288,8 @@ class Hid {
|
||||
static void Unlock() { pHid->Unlock(); }
|
||||
static bool Locked() { return pHid->Locked(); }
|
||||
static void Update() { pHid->Update(); }
|
||||
static u32 GetFlags() { return pHid->Flags; }
|
||||
static void GetStrInput(std::string& str) { pHid->GetInputStr(str); }
|
||||
|
||||
static HidDriver::Ref pHid;
|
||||
};
|
||||
|
@ -58,6 +58,9 @@ class PD_IMAGE_API Image {
|
||||
int Height() const { return pHeight; }
|
||||
Format Fmt() const { return pFmt; }
|
||||
|
||||
void FlipVertical();
|
||||
void FlipHorizontal();
|
||||
|
||||
u8& operator[](int idx) { return pBuffer[idx]; }
|
||||
u8 operator[](int idx) const { return pBuffer[idx]; }
|
||||
|
||||
|
@ -102,7 +102,7 @@ class PD_UI7_API IO {
|
||||
}
|
||||
|
||||
ViewPort::Ref GetViewPort(const ID& id) {
|
||||
if (ViewPorts.count(id)) {
|
||||
if (!ViewPorts.count(id)) {
|
||||
return nullptr;
|
||||
}
|
||||
return ViewPorts[id];
|
||||
|
@ -39,6 +39,7 @@ class PD_UI7_API Layout {
|
||||
this->IO = io;
|
||||
DrawList = Li::DrawList::New();
|
||||
DrawList->SetFont(IO->Font);
|
||||
DrawList->SetFontScale(io->FontScale);
|
||||
Scrolling[0] = false;
|
||||
Scrolling[1] = false;
|
||||
CursorInit();
|
||||
|
@ -37,7 +37,7 @@ SOFTWARE.
|
||||
* Major Minor Patch Build
|
||||
* 0x01010000 -> 1.1.0-0
|
||||
*/
|
||||
#define UI7_VERSION 0x00050000
|
||||
#define UI7_VERSION 0x00050001
|
||||
|
||||
namespace PD {
|
||||
namespace UI7 {
|
||||
|
@ -39,6 +39,20 @@ PD_CORE_API std::vector<u8> LoadFile2Mem(const std::string& path) {
|
||||
return res;
|
||||
}
|
||||
|
||||
PD_CORE_API std::string LoadFile2Str(const std::string& path) {
|
||||
std::ifstream iff(path, std::ios::binary);
|
||||
if (!iff) {
|
||||
return "";
|
||||
}
|
||||
std::string ret;
|
||||
std::string line;
|
||||
while (std::getline(iff, line)) {
|
||||
ret += line;
|
||||
}
|
||||
iff.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
PD_CORE_API u32 HashMemory(const std::vector<u8>& data) {
|
||||
u32 hash = 4477;
|
||||
for (auto& it : data) {
|
||||
|
@ -25,32 +25,98 @@ SOFTWARE.
|
||||
#include <pd/core/mat.hpp>
|
||||
|
||||
namespace PD {
|
||||
PD_CORE_API void Mat4::Zeros() {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
m[i] = 0.0f;
|
||||
}
|
||||
PD_CORE_API Mat4 Mat4::RotateX(float a) {
|
||||
float c = std::cos(a);
|
||||
float s = std::sin(a);
|
||||
Mat4 ret = Identity();
|
||||
ret(1, 1) = c;
|
||||
ret(1, 2) = -s;
|
||||
ret(2, 1) = s;
|
||||
ret(2, 2) = c;
|
||||
return ret;
|
||||
}
|
||||
|
||||
PD_CORE_API void Mat4::Ortho(float left, float right, float bottom, float top,
|
||||
float near, float far) {
|
||||
m[0] = 2.0f / (right - left);
|
||||
m[1] = 0.0f;
|
||||
m[2] = 0.0f;
|
||||
m[3] = -(right + left) / (right - left);
|
||||
PD_CORE_API Mat4 Mat4::RotateY(float a) {
|
||||
float c = std::cos(a);
|
||||
float s = std::sin(a);
|
||||
Mat4 ret = Identity();
|
||||
ret(0, 0) = c;
|
||||
ret(0, 2) = s;
|
||||
ret(2, 0) = -s;
|
||||
ret(2, 2) = c;
|
||||
return ret;
|
||||
}
|
||||
|
||||
m[4] = 0.0f;
|
||||
m[5] = 2.0f / (top - bottom);
|
||||
m[6] = 0.0f;
|
||||
m[7] = -(top + bottom) / (top - bottom);
|
||||
PD_CORE_API Mat4 Mat4::RotateZ(float a) {
|
||||
float c = std::cos(a);
|
||||
float s = std::sin(a);
|
||||
Mat4 ret = Identity();
|
||||
ret(0, 0) = c;
|
||||
ret(0, 1) = -s;
|
||||
ret(1, 0) = s;
|
||||
ret(1, 1) = c;
|
||||
return ret;
|
||||
}
|
||||
|
||||
m[8] = 0.0f;
|
||||
m[9] = 0.0f;
|
||||
m[10] = -2.0f / (far - near);
|
||||
m[11] = -(far + near) / (far - near);
|
||||
PD_CORE_API Mat4 Mat4::Rotate(fvec3 axis, float a) {
|
||||
float s = std::sin(a);
|
||||
float c = std::cos(a);
|
||||
float t = 1.f - c;
|
||||
axis = axis.Normalize();
|
||||
float x = axis.x;
|
||||
float y = axis.y;
|
||||
float z = axis.z;
|
||||
Mat4 ret = Identity();
|
||||
ret(0, 0) = t * x * x + c;
|
||||
ret(0, 1) = t * x * y - z * s;
|
||||
ret(0, 2) = t * x * z + y * s;
|
||||
|
||||
m[12] = 0.0f;
|
||||
m[13] = 0.0f;
|
||||
m[14] = 0.0f;
|
||||
m[15] = 1.0f;
|
||||
ret(1, 0) = t * x * y + z * s;
|
||||
ret(1, 1) = t * y * y + c;
|
||||
ret(1, 2) = t * y * z - x * s;
|
||||
|
||||
ret(2, 0) = t * x * z - y * s;
|
||||
ret(2, 1) = t * y * z + x * s;
|
||||
ret(2, 2) = t * z * z + c;
|
||||
return ret;
|
||||
}
|
||||
|
||||
PD_CORE_API Mat4 Mat4::Perspective(float fov, float aspect, float n, float f) {
|
||||
float _fov = std::tan(fov / 2.f);
|
||||
Mat4 ret;
|
||||
ret(0, 0) = 1.f / (aspect * _fov);
|
||||
ret(1, 1) = 1.f / _fov;
|
||||
#ifdef __3DS__
|
||||
ret(2, 3) = f * n / (n - f);
|
||||
ret(2, 2) = -(-1.f) * n / (n - f);
|
||||
#else
|
||||
ret(2, 2) = -(f + n) / (f - n);
|
||||
ret(2, 3) = -(2.f * f * n) / (f - n);
|
||||
#endif
|
||||
ret(3, 2) = -1.f;
|
||||
ret(3, 3) = 0.0f;
|
||||
return ret;
|
||||
}
|
||||
|
||||
PD_CORE_API Mat4 Mat4::LookAt(const fvec3& pos, const fvec3& center,
|
||||
const fvec3& up) {
|
||||
auto f = fvec3(center - pos).Normalize();
|
||||
auto s = f.Cross(up).Normalize();
|
||||
auto u = s.Cross(f);
|
||||
|
||||
Mat4 ret = Identity();
|
||||
ret(0, 0) = s.x;
|
||||
ret(0, 1) = s.y;
|
||||
ret(0, 2) = s.z;
|
||||
ret(1, 0) = u.x;
|
||||
ret(1, 1) = u.y;
|
||||
ret(1, 2) = u.z;
|
||||
ret(2, 0) = -f.x;
|
||||
ret(2, 1) = -f.y;
|
||||
ret(2, 2) = -f.z;
|
||||
ret(0, 3) = -s.Dot(pos);
|
||||
ret(1, 3) = -u.Dot(pos);
|
||||
ret(2, 3) = f.Dot(pos);
|
||||
return ret;
|
||||
}
|
||||
} // namespace PD
|
@ -5,6 +5,12 @@ namespace PD {
|
||||
PD_DEF_EXP(HidDriver::Ref, Hid::pHid);
|
||||
|
||||
bool HidDriver::IsEvent(Event e, Key keys) { return KeyEvents[0][e] & keys; }
|
||||
bool HidDriver::IsEvent(Event e, KbKey key) {
|
||||
if (!KbKeyEvents[0].count(key)) {
|
||||
return false;
|
||||
}
|
||||
return KbKeyEvents[0][key] == e;
|
||||
}
|
||||
|
||||
void HidDriver::SwapTab() {
|
||||
auto tkd = KeyEvents[1][Event_Down];
|
||||
|
@ -77,6 +77,46 @@ PD_IMAGE_API void Image::Copy(const std::vector<u8>& buf, int w, int h,
|
||||
}
|
||||
}
|
||||
|
||||
PD_IMAGE_API void Image::FlipHorizontal() {
|
||||
/**
|
||||
* Dont know if i am brain dead but i think this code
|
||||
* should Horizpntal flip an image
|
||||
* Probably this needs some optimisation like not always calling
|
||||
* Fmt2Bpp and use `* 0.5` instead of `/ 2` i guess
|
||||
*/
|
||||
for (int i = 0; i < pWidth / 2; i++) {
|
||||
for (int j = 0; j < pHeight; j++) {
|
||||
int src = (j * pWidth + i) * Fmt2Bpp(pFmt);
|
||||
int dst = (j * pWidth + (pWidth - 1 - i)) * Fmt2Bpp(pFmt);
|
||||
for (int k = 0; k < Fmt2Bpp(pFmt); k++) {
|
||||
PD::u8 tmp = pBuffer[dst + k];
|
||||
pBuffer[dst + k] = pBuffer[src + k];
|
||||
pBuffer[src + k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PD_IMAGE_API void Image::FlipVertical() {
|
||||
/**
|
||||
* Dont know if i am brain dead but i think this code
|
||||
* should Vertical flip an image
|
||||
* Probably this needs some optimisation like not always calling
|
||||
* Fmt2Bpp and use `* 0.5` instead of `/ 2` i guess
|
||||
*/
|
||||
for (int i = 0; i < pWidth; i++) {
|
||||
for (int j = 0; j < pHeight / 2; j++) {
|
||||
int src = (j * pWidth + i) * Fmt2Bpp(pFmt);
|
||||
int dst = ((pHeight - 1 - j) * pWidth + i) * Fmt2Bpp(pFmt);
|
||||
for (int k = 0; k < Fmt2Bpp(pFmt); k++) {
|
||||
PD::u8 tmp = pBuffer[dst + k];
|
||||
pBuffer[dst + k] = pBuffer[src + k];
|
||||
pBuffer[src + k] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PD_IMAGE_API void Image::Convert(Image::Ref img, Image::Format dst) {
|
||||
if (img->pFmt == dst) {
|
||||
return;
|
||||
|
@ -25,4 +25,4 @@ else()
|
||||
pd_add_lib(pd-ui7 SRC_FILES ${SRC})
|
||||
endif()
|
||||
|
||||
target_link_libraries(pd-ui7 PUBLIC pd-core)
|
||||
target_link_libraries(pd-ui7 PUBLIC pd-lithium pd-core)
|
@ -1,7 +1,18 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
project(lazyvec LANGUAGES CXX VERSION 1.0.0)
|
||||
project(lazyvec LANGUAGES CXX VERSION 2.0.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED true)
|
||||
|
||||
add_executable(lazyvec
|
||||
source/main.cpp
|
||||
|
||||
source/lazyconstructors.cpp
|
||||
source/lazyfuncs.cpp
|
||||
source/lazyops.cpp
|
||||
source/lazyoperation.cpp
|
||||
source/lazytemplate.cpp
|
||||
source/lazyswap.cpp
|
||||
)
|
||||
target_include_directories(lazyvec PUBLIC include)
|
||||
|
19
tools/lazyvec/include/lazyvec.hpp
Normal file
19
tools/lazyvec/include/lazyvec.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
/** Header for all source file functions */
|
||||
|
||||
#include <format> // yes this tool requires at least c++ 20
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace LVec {
|
||||
const std::vector<std::string> elems = {"x", "y", "z", "w"};
|
||||
std::string GenerateHeader(int n);
|
||||
std::string MakeOperationFor(char op, int n);
|
||||
std::string GenericOperations(int n);
|
||||
std::string MakeFunctions(int n);
|
||||
std::string MakeSwap(int n);
|
||||
std::string MakeConstructors(int n);
|
||||
} // namespace LVec
|
75
tools/lazyvec/source/lazyconstructors.cpp
Normal file
75
tools/lazyvec/source/lazyconstructors.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include <lazyvec.hpp>
|
||||
|
||||
constexpr std::string_view _construct = R"text(
|
||||
constexpr vec{0}() : {1} {{}}
|
||||
template <typename T1>
|
||||
constexpr vec{0}(T1 v) {{
|
||||
{2}
|
||||
}}
|
||||
|
||||
template <typename T1>
|
||||
constexpr vec{0}(const vec{0}<T1>& v) {{
|
||||
{3}
|
||||
}}
|
||||
|
||||
constexpr explicit vec{0}({4}) : {5} {{}}{6}
|
||||
)text";
|
||||
|
||||
constexpr std::string_view _extended3 = R"(
|
||||
|
||||
// Extended Constructors
|
||||
template <typename T1>
|
||||
constexpr explicit vec3(const vec2<T1>& xy, T1 z) {{
|
||||
x = (T)xy.x;
|
||||
y = (T)xy.y;
|
||||
this->z = (T)z;
|
||||
}}
|
||||
)";
|
||||
|
||||
constexpr std::string_view _extended4 = R"(
|
||||
|
||||
// Extended Constructors
|
||||
template <typename T1>
|
||||
constexpr explicit vec4(const vec2<T1>& xy, const vec2<T1>& zw) {{
|
||||
x = (T)xy.x;
|
||||
y = (T)xy.y;
|
||||
z = (T)zw.x;
|
||||
w = (T)zw.y;
|
||||
}}
|
||||
|
||||
template <typename T1>
|
||||
constexpr explicit vec4(const vec3<T1>& xyz, T1 w) {{
|
||||
x = (T)xyz.x;
|
||||
y = (T)xyz.y;
|
||||
z = (T)xyz.z;
|
||||
this->w = (T)w;
|
||||
}}
|
||||
)";
|
||||
|
||||
namespace LVec {
|
||||
std::string MakeConstructors(int n) {
|
||||
std::stringstream s1, s2, s3, s4, s5;
|
||||
for (int i = 0; i < n; i++) {
|
||||
s1 << elems[i] << "(0)";
|
||||
s2 << " " << elems[i] << " = (T)v;";
|
||||
s3 << " " << elems[i] << " = (T)v." << elems[i] << ";";
|
||||
s4 << "T " << elems[i];
|
||||
s5 << elems[i] << "(" << elems[i] << ")";
|
||||
if (i != n - 1) {
|
||||
s1 << ", ";
|
||||
s2 << std::endl;
|
||||
s3 << std::endl;
|
||||
s4 << ", ";
|
||||
s5 << ", ";
|
||||
}
|
||||
}
|
||||
std::string extended;
|
||||
if (n == 3) {
|
||||
extended = _extended3;
|
||||
} else if (n == 4) {
|
||||
extended = _extended4;
|
||||
}
|
||||
return std::format(_construct, n, s1.str(), s2.str(), s3.str(), s4.str(),
|
||||
s5.str(), extended);
|
||||
}
|
||||
} // namespace LVec
|
50
tools/lazyvec/source/lazyfuncs.cpp
Normal file
50
tools/lazyvec/source/lazyfuncs.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include <lazyvec.hpp>
|
||||
|
||||
constexpr std::string_view _funcs = R"text(
|
||||
double Len() const {{ return std::sqrt(SqLen()); }}
|
||||
double SqLen() const {{ return {1}; }}
|
||||
|
||||
template <typename T1>
|
||||
double Distance(const vec{0}<T1>& v) const {{
|
||||
return (*this - v).Len();
|
||||
}}
|
||||
|
||||
vec{0}<T> Normalize() const {{
|
||||
double l = Len();
|
||||
if(l == 0) {{
|
||||
return *this;
|
||||
}}
|
||||
return *this / (T)l;
|
||||
}}
|
||||
|
||||
template <typename T1>
|
||||
T Dot(const vec{0}<T1>&v) const {{
|
||||
return {2};
|
||||
}}
|
||||
)text";
|
||||
|
||||
constexpr std::string_view _cross = R"text(
|
||||
template <typename T1>
|
||||
vec3<T> Cross(const vec3<T1>& v) const {
|
||||
return vec3<T>(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||||
}
|
||||
)text";
|
||||
|
||||
namespace LVec {
|
||||
std::string MakeFunctions(int n) {
|
||||
std::stringstream s1, s2;
|
||||
for (int i = 0; i < n; i++) {
|
||||
s1 << elems[i] << " * " << elems[i];
|
||||
s2 << elems[i] << " * (T)v." << elems[i];
|
||||
if (i != n - 1) {
|
||||
s1 << " + ";
|
||||
s2 << " + ";
|
||||
}
|
||||
}
|
||||
std::string ret = std::format(_funcs, n, s1.str(), s2.str());
|
||||
if (n == 3) {
|
||||
ret += _cross;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace LVec
|
47
tools/lazyvec/source/lazyoperation.cpp
Normal file
47
tools/lazyvec/source/lazyoperation.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
#include <lazyvec.hpp>
|
||||
|
||||
constexpr std::string_view _op_template = R"text(
|
||||
template <typename T1>
|
||||
vec{0}<T>& operator{1}=(T1 v) {{
|
||||
{2}
|
||||
return *this;
|
||||
}}
|
||||
|
||||
template <typename T1>
|
||||
vec{0}<T>& operator{1}=(const vec{0}<T1>& v) {{
|
||||
{3}
|
||||
return *this;
|
||||
}}
|
||||
|
||||
template <typename T1>
|
||||
vec{0}<T> operator{1}(T1 v) const {{
|
||||
return vec{0}<T>({4});
|
||||
}}
|
||||
|
||||
template <typename T1>
|
||||
vec{0}<T> operator{1}(const vec{0}<T1>& v) const {{
|
||||
return vec{0}<T>({5});
|
||||
}}
|
||||
)text";
|
||||
|
||||
namespace LVec {
|
||||
std::string MakeOperationFor(char op, int n) {
|
||||
const std::string& toff = " ";
|
||||
// Create for streams for the operations functions
|
||||
std::stringstream s1, s2, s3, s4;
|
||||
for (int i = 0; i < n; i++) {
|
||||
s1 << toff << elems[i] << " " << op << "= (T)v;";
|
||||
s2 << toff << elems[i] << " " << op << "= (T)v." << elems[i] << ";";
|
||||
s3 << elems[i] << " " << op << " (T)v";
|
||||
s4 << elems[i] << " " << op << " (T)v." << elems[i];
|
||||
if (i != n - 1) {
|
||||
s1 << std::endl;
|
||||
s2 << std::endl;
|
||||
s3 << ", ";
|
||||
s4 << ", ";
|
||||
}
|
||||
}
|
||||
return std::format(_op_template, n, op, s1.str(), s2.str(), s3.str(),
|
||||
s4.str());
|
||||
}
|
||||
} // namespace LVec
|
30
tools/lazyvec/source/lazyops.cpp
Normal file
30
tools/lazyvec/source/lazyops.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include <lazyvec.hpp>
|
||||
|
||||
/**
|
||||
* Diffrence between lazyoperation.cpp and lazyops.cpp ?
|
||||
* One is for Operators with an input sym like +, -, * or /
|
||||
* the other (this) is for generic operations
|
||||
*/
|
||||
|
||||
constexpr std::string_view _generic_ops = R"text(
|
||||
vec{0} operator-() const {{ return vec{0}({1}); }}
|
||||
template <typename T1>
|
||||
bool operator==(const vec{0}<T1>& v) const {{ return {2}; }}
|
||||
template <typename T1>
|
||||
bool operator!=(const vec{0}<T1>& v) const {{ return !(*this == v); }}
|
||||
)text";
|
||||
|
||||
namespace LVec {
|
||||
std::string GenericOperations(int n) {
|
||||
std::stringstream s1, s2;
|
||||
for (int i = 0; i < n; i++) {
|
||||
s1 << "-" << elems[i];
|
||||
s2 << elems[i] << " == (T)v." << elems[i];
|
||||
if (i != n - 1) {
|
||||
s1 << ", ";
|
||||
s2 << " && ";
|
||||
}
|
||||
}
|
||||
return std::format(_generic_ops, n, s1.str(), s2.str());
|
||||
}
|
||||
} // namespace LVec
|
25
tools/lazyvec/source/lazyswap.cpp
Normal file
25
tools/lazyvec/source/lazyswap.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include <lazyvec.hpp>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace LVec {
|
||||
std::string MakeSwap(int n) {
|
||||
std::stringstream s;
|
||||
std::unordered_set<std::string> done;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
std::string a = elems[i];
|
||||
std::string b = elems[j];
|
||||
/** Make sure we generate nothing twice */
|
||||
if (a == b || done.count(b + a)) {
|
||||
continue;
|
||||
}
|
||||
s << " void Swap" << (char)toupper(a[0]) << (char)toupper(b[0])
|
||||
<< "() {\n";
|
||||
s << " T t = " << a << ";\n " << a << " = " << b << ";\n";
|
||||
s << " " << b << " = t;\n }\n";
|
||||
done.insert(a + b);
|
||||
}
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
} // namespace LVec
|
77
tools/lazyvec/source/lazytemplate.cpp
Normal file
77
tools/lazyvec/source/lazytemplate.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
#include <lazyvec.hpp>
|
||||
|
||||
constexpr std::string_view _template = R"text(#pragma once
|
||||
|
||||
/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file is generated by lazyvec 2.0.0
|
||||
|
||||
#include <pd/core/common.hpp>
|
||||
{7}
|
||||
|
||||
namespace PD {{
|
||||
template <typename T>
|
||||
class vec{0} {{
|
||||
public:
|
||||
{1}
|
||||
// Constructors
|
||||
{2}
|
||||
// Operations
|
||||
{3}
|
||||
// Generic Operations
|
||||
{4}
|
||||
// Functions
|
||||
{5}
|
||||
// Swap Functions
|
||||
{6}
|
||||
}};
|
||||
using fvec{0} = vec{0}<float>;
|
||||
using ivec{0} = vec{0}<int>;
|
||||
using dvec{0} = vec{0}<double>;
|
||||
}} // namespace PD
|
||||
)text";
|
||||
|
||||
namespace LVec {
|
||||
std::string GenerateHeader(int n) {
|
||||
std::stringstream ops, data, extended;
|
||||
for (int i = 0; i < n; i++) {
|
||||
data << "T " << elems[i] << ";" << std::endl;
|
||||
}
|
||||
ops << MakeOperationFor('+', n);
|
||||
ops << MakeOperationFor('-', n);
|
||||
ops << MakeOperationFor('*', n);
|
||||
ops << MakeOperationFor('/', n);
|
||||
if (n > 2) {
|
||||
extended << "// Extended includes (rename if you use other filenames/paths)"
|
||||
<< std::endl;
|
||||
extended << "#include <vec2.hpp>" << std::endl;
|
||||
if (n == 4) {
|
||||
extended << "#include <vec3.hpp>" << std::endl;
|
||||
}
|
||||
}
|
||||
return std::format(_template, n, data.str(), MakeConstructors(n), ops.str(),
|
||||
GenericOperations(n), MakeFunctions(n), MakeSwap(n),
|
||||
extended.str());
|
||||
}
|
||||
} // namespace LVec
|
@ -21,194 +21,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
const char* license_text = R"(/*
|
||||
MIT License
|
||||
Copyright (c) 2024 - 2025 René Amthor (tobid7)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
)";
|
||||
|
||||
const std::vector<std::string> elems = {"x", "y", "z", "w"};
|
||||
|
||||
void MakeOperationFor(std::fstream& off, char op, int n) {
|
||||
off << " template <typename T1>\n";
|
||||
off << " vec" << n << "<T>& operator" << op << "=(T1 v) {\n";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << " " << elems[i] << " " << op << "= (T)v;\n";
|
||||
}
|
||||
off << " return *this;\n";
|
||||
off << " }\n\n";
|
||||
|
||||
off << " template <typename T1>\n";
|
||||
off << " vec" << n << "<T>& operator" << op << "=(const vec" << n
|
||||
<< "<T1>& v) {\n";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << " " << elems[i] << " " << op << "= (T)v." << elems[i] << ";\n";
|
||||
}
|
||||
off << " return *this;\n";
|
||||
off << " }\n\n";
|
||||
|
||||
off << " template <typename T1>\n";
|
||||
off << " vec" << n << "<T> operator" << op << "(T1 v) const {\n";
|
||||
off << " return vec" << n << "<T>(";
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) off << ", ";
|
||||
off << elems[i] << " " << op << " (T)v";
|
||||
}
|
||||
off << ");\n }\n\n";
|
||||
|
||||
off << " template <typename T1>\n";
|
||||
off << " vec" << n << "<T> operator" << op << "(const vec" << n
|
||||
<< "<T1>& v) const {\n";
|
||||
off << " return vec" << n << "<T>(";
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) off << ", ";
|
||||
off << elems[i] << " " << op << " (T)v." << elems[i];
|
||||
}
|
||||
off << ");\n }\n\n";
|
||||
}
|
||||
|
||||
void SwapHaxx(std::fstream& off, int n) {
|
||||
std::unordered_set<std::string> done;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int j = 0; j < n; j++) {
|
||||
std::string a = elems[i];
|
||||
std::string b = elems[j];
|
||||
/** Make sure we generate nothing twice */
|
||||
if (a == b || done.count(b + a)) {
|
||||
continue;
|
||||
}
|
||||
off << " void Swap" << (char)toupper(a[0]) << (char)toupper(b[0])
|
||||
<< "() {\n";
|
||||
off << " T t = " << a << ";\n " << a << " = " << b << ";\n";
|
||||
off << " " << b << " = t;\n }\n";
|
||||
done.insert(a + b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateVec(int n) {
|
||||
if (n < 2 || n > 4) {
|
||||
std::cout << "Only 2 to 4 supported.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
std::fstream off("vec" + std::to_string(n) + ".hpp", std::ios::out);
|
||||
|
||||
off << "#pragma once\n" << std::endl;
|
||||
off << license_text << std::endl;
|
||||
off << "// This file is generated by lazyvec\n#include "
|
||||
"<pd/core/common.hpp>\n\n";
|
||||
off << "namespace PD {" << std::endl;
|
||||
off << "template <typename T>\nclass vec" << n << " {\npublic:\n";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << " T " << elems[i] << ";\n";
|
||||
}
|
||||
off << "\n";
|
||||
off << " vec" << n << "(): ";
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) {
|
||||
off << ", ";
|
||||
}
|
||||
off << elems[i] << "(0)";
|
||||
}
|
||||
off << " {}" << std::endl;
|
||||
// Magic Construtor (support for anytype vec)
|
||||
off << " template <typename T1>\n";
|
||||
off << " explicit vec" << n << "(T1 v) {\n";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << " " << elems[i] << " = (T)v;\n";
|
||||
}
|
||||
off << " }\n\n";
|
||||
|
||||
// Magic Constructor 2
|
||||
off << " template <typename T1>\n";
|
||||
off << " explicit vec" << n << "(vec" << n << "<T1> v) {\n";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << " " << elems[i] << " = (T)v. " << elems[i] << ";\n";
|
||||
}
|
||||
off << " }\n\n";
|
||||
|
||||
off << " vec" << n << "(";
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) off << ", ";
|
||||
off << "T " << elems[i];
|
||||
}
|
||||
off << ") : ";
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i > 0) off << ", ";
|
||||
off << elems[i] << "(" << elems[i] << ")";
|
||||
}
|
||||
off << " {}\n\n";
|
||||
|
||||
MakeOperationFor(off, '+', n);
|
||||
MakeOperationFor(off, '-', n);
|
||||
MakeOperationFor(off, '*', n);
|
||||
MakeOperationFor(off, '/', n);
|
||||
|
||||
off << " vec" << n << " operator-() const {return vec" << n << "(";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << "-" << elems[i];
|
||||
if (i != n - 1) {
|
||||
off << ", ";
|
||||
}
|
||||
}
|
||||
off << ");}\n\n";
|
||||
|
||||
off << " bool operator==(const vec" << n << "& v) const { return ";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << elems[i] << " == v." << elems[i];
|
||||
if (i != n - 1) {
|
||||
off << " && ";
|
||||
}
|
||||
}
|
||||
off << ";}\n";
|
||||
off << " bool operator!=(const vec" << n
|
||||
<< "&v) const { return !(*this == v); }\n\n";
|
||||
|
||||
off << " double Len() const {return std::sqrt(SqLen()); }\n";
|
||||
off << " double SqLen() const { return ";
|
||||
for (int i = 0; i < n; i++) {
|
||||
off << elems[i] << " * " << elems[i];
|
||||
if (i != n - 1) {
|
||||
off << " + ";
|
||||
}
|
||||
}
|
||||
off << "; }\n\n";
|
||||
|
||||
SwapHaxx(off, n);
|
||||
|
||||
off << "};\n";
|
||||
off << "using fvec" << n << " = vec" << n << "<float>;\n";
|
||||
off << "using dvec" << n << " = vec" << n << "<double>;\n";
|
||||
off << "using ivec" << n << " = vec" << n << "<int>;\n";
|
||||
off << "}\n";
|
||||
off.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Yet another Stupid Code generation tool
|
||||
* Why ?
|
||||
@ -216,11 +28,21 @@ void GenerateVec(int n) {
|
||||
* manually writeup vec2 to vec4
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <lazyvec.hpp>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 2) {
|
||||
std::cout << argv[0] << " <num (2 to 4)>" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
GenerateVec(std::stoi(argv[1]));
|
||||
int l = std::stoi(argv[1]);
|
||||
if (l < 2 || l > 4) {
|
||||
std::cout << argv[0] << " <num (2 to 4)>" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
std::ofstream f("vec" + std::to_string(l) + ".hpp");
|
||||
f << LVec::GenerateHeader(l);
|
||||
f.close();
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user