optimized sub-optimal code

This commit is contained in:
sillysagiri 2023-10-14 12:17:58 +07:00
parent ffd4b59eca
commit 9afe1d0993
18 changed files with 704 additions and 444 deletions

View File

@ -10,10 +10,10 @@ set(PROJECT_VERSION 1.0)
project(${PROJECT_NAME} VERSION ${PROJECT_VERSION})
##############################################################
set(RAYLIB_DIR "/home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/raylib-4.5.0")
set(IMGUI_DIR "/home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/imgui-docking")
set(RLIMGUI_DIR "/home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/rlImGui")
set(INIFILE_DIR "/home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/inifile-cpp")
set(RAYLIB_DIR "/run/media/sillysagiri/linux-home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/raylib-4.5.0")
set(IMGUI_DIR "/run/media/sillysagiri/linux-home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/imgui-docking")
set(RLIMGUI_DIR "/run/media/sillysagiri/linux-home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/rlImGui")
set(INIFILE_DIR "/run/media/sillysagiri/linux-home/tuanpanda/Panda/04-WORKSPACE/00-PROGRAMMING/_Git Clone/inifile-cpp")
### Fallback link
set(RAYLIB_LINK "https://github.com/raysan5/raylib/archive/refs/tags/4.5.0.zip")

124
src/Panda.hpp Executable file
View File

@ -0,0 +1,124 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include "utils/Random.hpp"
struct Texture;
struct RenderTexture;
struct Color;
struct Vector2;
struct Rectangle;
namespace panda
{
struct TextureAtlasItem
{
int x;
int y;
int w;
int h;
float px;
float py;
};
class Scene {
public:
Scene() {}
virtual ~Scene() {}
virtual void update() {}
};
struct Sprite {
Texture *texture;
float x = 0.0f;
float y = 0.0f;
float scaleX = 1.0f;
float scaleY = 1.0f;
float rotation = 0.0f;
void Load(const char* path);
void Unload();
void Draw(Color color);
void SetPivot(Vector2 ratio);
void SetPivotRatio(Vector2 ratio);
void SetFlip(bool x, bool y);
void SetFlipX(bool x);
void SetFlipY(bool y);
Vector2 GetPivot();
Vector2 GetPivotFlip();
bool GetFlipX();
bool GetFlipY();
private:
bool flipX = false;
bool flipY = false;
float pivotX = 0.0f;
float pivotY = 0.0f;
float pivotX_flip = 0.0f;
float pivotY_flip = 0.0f;
void CalculatePivotFlip();
};
struct Matrix {
float a = 1.0f;
float b = 0.0f;
float c = 0.0f;
float d = 1.0f;
float tx = 0.0f;
float ty = 0.0f;
void identity();
void translate(float dx, float dy);
void rotate(float radian);
void scale(float sx, float sy);
void concat(Matrix m);
};
// ############################################################################################
// Core
void CreateWindow(int w, int h, const char *str);
void AppUpdate();
void SetScene(Scene* scene);
Scene* GetScene();
// # Graphic
// ### GUI
void GuiInit();
void GuiDestroy();
void GuiBegin();
void GuiEnd();
// ### atlas
bool LoadTextureAtlas(const char *image_path, const char *ini_path, std::string AtlasKey);
bool UnloadTextureAtlas(std::string AtlasKey);
void DrawTextureAtlas(std::string AtlasKey, std::string key, int x, int y);
void DrawTextureAtlasPro(std::string AtlasKey, std::string key, int x, int y, Color color, bool flipX = false, bool flipY = false);
// ### draw
void DrawTextureTiled(Texture texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint);
void DrawRenderTexture(const RenderTexture &buffer, const float &x, const float &y, const Color &color);
// ### texture utils
Rectangle GetTextureRect(const Texture &tex, bool flipX, bool flipY);
// Utils
Random &GetDefaultRandom();
// Euclidean Distance
double distance(const Vector2 &p1, const Vector2 &p2);
double distanceSqrt(const Vector2 &p1, const Vector2 &p2);
// Manhattan Distance
double distanceManhattan(const Vector2 &p1, const Vector2 &p2);
}

View File

@ -1,8 +1,8 @@
#include <raylib.h>
#include "core/Panda.hpp"
#include "Panda.hpp"
static Scene* currentScene = nullptr;
static panda::Scene* currentScene = nullptr;
// CORE
void panda::CreateWindow(int w, int h, const char *str)
@ -10,7 +10,7 @@ void panda::CreateWindow(int w, int h, const char *str)
Random::getInstance().setSeedFromTime();
SetConfigFlags(
FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE);
#if PLATFORM_ANDROID
InitWindow(0, 0, str);
@ -19,7 +19,6 @@ void panda::CreateWindow(int w, int h, const char *str)
SetWindowMinSize(w*0.8f, h*0.8f);
#endif
// SetTargetFPS(60);
SetExitKey(-1);
}
@ -40,7 +39,7 @@ void panda::SetScene(Scene* scene)
currentScene = scene;
}
Scene* panda::GetScene()
panda::Scene* panda::GetScene()
{
return currentScene;
}

View File

@ -1,9 +1,10 @@
#include <imgui.h>
#include <rlImGui.h>
#include <rlgl.h>
#include <stdbool.h>
#include <raylib.h>
#include "core/Panda.hpp"
#include "raylib.h"
#include "Panda.hpp"
#if PLATFORM_ANDROID
@ -15,77 +16,82 @@ extern "C" struct android_app *GetAndroidApp(void);
static int32_t handleInputEvent(struct android_app* app, AInputEvent* inputEvent)
{
return ImGui_ImplAndroid_HandleInputEvent(inputEvent);
return ImGui_ImplAndroid_HandleInputEvent(inputEvent);
}
#endif
void panda::GuiInit()
{
#if PLATFORM_ANDROID
GetAndroidApp()->onInputEvent = handleInputEvent;
#if PLATFORM_ANDROID
GetAndroidApp()->onInputEvent = handleInputEvent;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.IniFilename = NULL;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.IniFilename = NULL;
ImGui::StyleColorsDark();
ImGui_ImplAndroid_Init(GetAndroidApp()->window);
ImGui_ImplOpenGL3_Init("#version 300 es");
ImGui::StyleColorsDark();
ImGui_ImplAndroid_Init(GetAndroidApp()->window);
ImGui_ImplOpenGL3_Init("#version 300 es");
ImFontConfig font_cfg;
font_cfg.SizePixels = 22.0f;
io.Fonts->AddFontDefault(&font_cfg);
ImGui::GetStyle().ScaleAllSizes(3.0f);
#else
rlImGuiSetup(true);
#endif
ImFontConfig font_cfg;
font_cfg.SizePixels = 22.0f;
io.Fonts->AddFontDefault(&font_cfg);
ImGui::GetStyle().ScaleAllSizes(3.0f);
#else
rlImGuiSetup(true);
#endif
}
void panda::GuiDestroy()
{
#if PLATFORM_ANDROID
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplAndroid_Shutdown();
ImGui::DestroyContext();
#else
rlImGuiShutdown();
#endif
#if PLATFORM_ANDROID
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplAndroid_Shutdown();
ImGui::DestroyContext();
#else
rlImGuiShutdown();
#endif
}
void panda::GuiBegin()
{
#if PLATFORM_ANDROID
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplAndroid_NewFrame();
ImGui::NewFrame();
#else
rlImGuiBegin();
#endif
#if PLATFORM_ANDROID
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplAndroid_NewFrame();
ImGui::NewFrame();
#else
rlImGuiBegin();
#endif
}
void panda::GuiEnd()
{
#if PLATFORM_ANDROID
rlDrawRenderBatchActive();
rlDisableBackfaceCulling();
#if PLATFORM_ANDROID
rlDrawRenderBatchActive();
rlDisableBackfaceCulling();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
rlSetTexture(0);
rlEnableBackfaceCulling();
#else
rlImGuiEnd();
#endif
rlSetTexture(0);
rlEnableBackfaceCulling();
#else
rlImGuiEnd();
#endif
}
void panda::DrawRenderTexture(const RenderTexture &buffer, const float &x, const float &y, const Color &color)
{
DrawTextureRec(
buffer.texture,
{0.0f, 0.0f, 1.0f*buffer.texture.width, -1.0f*buffer.texture.height},
{x, y}, color);
DrawTextureRec(
buffer.texture,
{0.0f, 0.0f, 1.0f*buffer.texture.width, -1.0f*buffer.texture.height},
{x, y}, color);
}
Rectangle panda::GetTextureRect(const Texture &tex, bool flipX, bool flipY)
{
return { 0.0f, 0.0f, (flipX ? -tex.width : tex.width)*1.0f, (flipY ? -tex.height : tex.height)*1.0f };
}
/////////////////////////////////

View File

@ -1,60 +0,0 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include "core/Scene.hpp"
#include "utils/Random.hpp"
struct Texture;
struct RenderTexture;
struct Color;
struct Vector2;
namespace panda
{
struct TextureAtlasItem
{
int x;
int y;
int w;
int h;
float px;
float py;
};
// Core
void CreateWindow(int w, int h, const char *str);
void AppUpdate();
void SetScene(Scene* scene);
Scene* GetScene();
// Graphic
void GuiInit();
void GuiDestroy();
void GuiBegin();
void GuiEnd();
bool LoadTextureAtlas(const char *image_path, const char *ini_path, std::string AtlasKey);
bool UnloadTextureAtlas(std::string AtlasKey);
void DrawTextureAtlas(std::string AtlasKey, std::string key, int x, int y);
void DrawTextureAtlasPro(std::string AtlasKey, std::string key, int x, int y, Color color, bool flipX = false, bool flipY = false);
void DrawRenderTexture(const RenderTexture &buffer, const float &x, const float &y, const Color &color);
// Tilemap
// TilemapMetadata LoadTilemapMetadata(const char *file);
// TilemapItem LoadTilemap(const char *file, TilemapMetadata metadata, Texture texture);
// Utils
Random &GetDefaultRandom();
// Euclidean Distance
double distance(const Vector2 &p1, const Vector2 &p2);
double distanceSqrt(const Vector2 &p1, const Vector2 &p2);
// Manhattan Distance
double distanceManhattan(const Vector2 &p1, const Vector2 &p2);
}

View File

@ -1,8 +0,0 @@
#pragma once
class Scene {
public:
Scene() {}
virtual ~Scene() {}
virtual void update() {}
};

98
src/display/Sprite.cpp Normal file
View File

@ -0,0 +1,98 @@
#include <raylib.h>
#include "Panda.hpp"
namespace panda {
void Sprite::Load(const char* path)
{
texture = new Texture(LoadTexture(path));
}
void Sprite::Unload()
{
UnloadTexture(*texture);
}
void Sprite::Draw(Color color)
{
Vector2 pivot_temp = (flipX || flipY) ? Vector2{pivotX_flip, pivotY_flip} : Vector2{pivotX, pivotY};
panda::Matrix matrix;
matrix.translate(-pivot_temp.x, -pivot_temp.y);
matrix.scale(scaleX, scaleY);
matrix.rotate(rotation * DEG2RAD);
matrix.translate(x, y);
DrawTexturePro(
*texture,
panda::GetTextureRect(*texture, flipX, flipY),
{
matrix.tx, matrix.ty,
scaleX*texture->width,
scaleY*texture->height
},
{0.0f, 0.0f},
rotation, color
);
}
void Sprite::SetPivot(Vector2 p)
{
pivotX = p.x;
pivotY = p.y;
CalculatePivotFlip();
}
void Sprite::SetPivotRatio(Vector2 ratio)
{
pivotX = texture->width*ratio.x;
pivotY = texture->height*ratio.y;
CalculatePivotFlip();
}
void Sprite::SetFlip(bool x, bool y)
{
flipX = x;
flipY = y;
CalculatePivotFlip();
}
void Sprite::SetFlipX(bool x)
{
flipX = x;
CalculatePivotFlip();
}
void Sprite::SetFlipY(bool y)
{
flipY = y;
CalculatePivotFlip();
}
Vector2 Sprite::GetPivot()
{
return {pivotX, pivotY};
}
Vector2 Sprite::GetPivotFlip()
{
return {pivotX_flip, pivotY_flip};
}
bool Sprite::GetFlipX()
{
return flipX;
}
bool Sprite::GetFlipY()
{
return flipY;
}
void Sprite::CalculatePivotFlip()
{
pivotX_flip = flipX ? texture->width-pivotX : pivotX;
pivotY_flip = flipY ? texture->height-pivotY : pivotY;
}
}

View File

@ -1,7 +1,8 @@
#include "core/Panda.hpp"
#include <cmath>
#include <raylib.h>
#include "Panda.hpp"
double panda::distance(const Vector2 &p1, const Vector2 &p2)
{
double dx = p1.x - p2.x;

View File

@ -1,7 +1,7 @@
#include "utils/Easing.hpp"
#include <cmath>
#include "utils/Easing.hpp"
namespace cur = easing;
#ifndef PI
@ -9,165 +9,165 @@ namespace cur = easing;
#endif
double cur::inSine(double t) {
return sin(1.5707963 * t);
return sin(1.5707963 * t);
}
double cur::outSine(double t) {
return 1 + sin(1.5707963 * (--t));
return 1 + sin(1.5707963 * (--t));
}
double cur::inOutSine(double t) {
return 0.5 * (1 + sin(3.1415926 * (t - 0.5)));
return 0.5 * (1 + sin(3.1415926 * (t - 0.5)));
}
double cur::inQuad(double t) {
return t * t;
return t * t;
}
double cur::outQuad(double t) {
return t * (2 - t);
return t * (2 - t);
}
double cur::inOutQuad(double t) {
return t < 0.5 ? 2 * t * t : t * (4 - 2 * t) - 1;
return t < 0.5 ? 2 * t * t : t * (4 - 2 * t) - 1;
}
double cur::inCubic(double t) {
return t * t * t;
return t * t * t;
}
double cur::outCubic(double t) {
return 1 + (--t) * t * t;
return 1 + (--t) * t * t;
}
double cur::inOutCubic(double t) {
return t < 0.5 ? 4 * t * t * t : 1 + (--t) * (2 * (--t)) * (2 * t);
return t < 0.5 ? 4 * t * t * t : 1 + (--t) * (2 * (--t)) * (2 * t);
}
double cur::inQuart(double t) {
t *= t;
return t * t;
t *= t;
return t * t;
}
double cur::outQuart(double t) {
t = (--t) * t;
return 1 - t * t;
t = (--t) * t;
return 1 - t * t;
}
double cur::inOutQuart(double t) {
if(t < 0.5) {
t *= t;
return 8 * t * t;
} else {
t = (--t) * t;
return 1 - 8 * t * t;
}
if(t < 0.5) {
t *= t;
return 8 * t * t;
} else {
t = (--t) * t;
return 1 - 8 * t * t;
}
}
double cur::inQuint(double t) {
auto t2 = t * t;
return t * t2 * t2;
auto t2 = t * t;
return t * t2 * t2;
}
double cur::outQuint(double t) {
auto t2 = (--t) * t;
return 1 + t * t2 * t2;
auto t2 = (--t) * t;
return 1 + t * t2 * t2;
}
double cur::inOutQuint(double t) {
auto t2 = double { 0.0 };
if(t < 0.5) {
t2 = t * t;
return 16 * t * t2 * t2;
} else {
t2 = (--t) * t;
return 1 + 16 * t * t2 * t2;
}
auto t2 = double { 0.0 };
if(t < 0.5) {
t2 = t * t;
return 16 * t * t2 * t2;
} else {
t2 = (--t) * t;
return 1 + 16 * t * t2 * t2;
}
}
double cur::inExpo(double t) {
return (pow(2, 8 * t) - 1) / 255;
return (pow(2, 8 * t) - 1) / 255;
}
double cur::outExpo(double t) {
return 1 - pow(2, -8 * t);
return 1 - pow(2, -8 * t);
}
double cur::inOutExpo(double t) {
if(t < 0.5) {
return (pow(2, 16 * t) - 1) / 510;
} else {
return 1 - 0.5 * pow(2, -16 * (t - 0.5));
}
if(t < 0.5) {
return (pow(2, 16 * t) - 1) / 510;
} else {
return 1 - 0.5 * pow(2, -16 * (t - 0.5));
}
}
double cur::inCirc(double t) {
return 1 - sqrt(1 - t);
return 1 - sqrt(1 - t);
}
double cur::outCirc(double t) {
return sqrt(t);
return sqrt(t);
}
double cur::inOutCirc(double t) {
if(t < 0.5) {
return (1 - sqrt(1 - 2 * t)) * 0.5;
} else {
return (1 + sqrt(2 * t - 1)) * 0.5;
}
if(t < 0.5) {
return (1 - sqrt(1 - 2 * t)) * 0.5;
} else {
return (1 + sqrt(2 * t - 1)) * 0.5;
}
}
double cur::inBack(double t) {
return t * t * (2.70158 * t - 1.70158);
return t * t * (2.70158 * t - 1.70158);
}
double cur::outBack(double t) {
return 1 + (--t) * t * (2.70158 * t + 1.70158);
return 1 + (--t) * t * (2.70158 * t + 1.70158);
}
double cur::inOutBack(double t) {
if(t < 0.5) {
return t * t * (7 * t - 2.5) * 2;
} else {
return 1 + (--t) * t * 2 * (7 * t + 2.5);
}
if(t < 0.5) {
return t * t * (7 * t - 2.5) * 2;
} else {
return 1 + (--t) * t * 2 * (7 * t + 2.5);
}
}
double cur::inElastic(double t) {
auto t2 = t * t;
return t2 * t2 * sin(t * PI * 4.5);
auto t2 = t * t;
return t2 * t2 * sin(t * PI * 4.5);
}
double cur::outElastic(double t) {
auto t2 = (t - 1) * (t - 1);
return 1 - t2 * t2 * cos(t * PI * 4.5);
auto t2 = (t - 1) * (t - 1);
return 1 - t2 * t2 * cos(t * PI * 4.5);
}
double cur::inOutElastic(double t) {
auto t2 = double { 0.0 };
if(t < 0.45) {
t2 = t * t;
return 8 * t2 * t2 * sin(t * PI * 9);
} else if(t < 0.55) {
return 0.5 + 0.75 * sin(t * PI * 4);
} else {
t2 = (t - 1) * (t - 1);
return 1 - 8 * t2 * t2 * sin(t * PI * 9);
}
auto t2 = double { 0.0 };
if(t < 0.45) {
t2 = t * t;
return 8 * t2 * t2 * sin(t * PI * 9);
} else if(t < 0.55) {
return 0.5 + 0.75 * sin(t * PI * 4);
} else {
t2 = (t - 1) * (t - 1);
return 1 - 8 * t2 * t2 * sin(t * PI * 9);
}
}
double cur::inBounce(double t) {
return pow(2, 6 * (t - 1)) * abs(sin(t * PI * 3.5));
return pow(2, 6 * (t - 1)) * abs(sin(t * PI * 3.5));
}
double cur::outBounce(double t) {
return 1 - pow(2, -6 * t) * abs(cos(t * PI * 3.5));
return 1 - pow(2, -6 * t) * abs(cos(t * PI * 3.5));
}
double cur::inOutBounce(double t) {
if(t < 0.5) {
return 8 * pow(2, 8 * (t - 1)) * abs(sin(t * PI * 7));
} else {
return 1 - 8 * pow(2, -8 * t) * abs(sin(t * PI * 7));
}
if(t < 0.5) {
return 8 * pow(2, 8 * (t - 1)) * abs(sin(t * PI * 7));
} else {
return 1 - 8 * pow(2, -8 * t) * abs(sin(t * PI * 7));
}
}

View File

@ -2,35 +2,35 @@
namespace easing
{
double inSine(double time);
double outSine(double time);
double inOutSine(double time);
double inQuad(double time);
double outQuad(double time);
double inOutQuad(double time);
double inCubic(double time);
double outCubic(double time);
double inOutCubic(double time);
double inQuart(double time);
double outQuart(double time);
double inOutQuart(double time);
double inQuint(double time);
double outQuint(double time);
double inOutQuint(double time);
double inExpo(double time);
double outExpo(double time);
double inOutExpo(double time);
double inOutExpo(double time);
double inCirc(double time);
double outCirc(double time);
double inOutCirc(double time);
double inBack(double time);
double outBack(double time);
double inOutBack(double time);
double inElastic(double time);
double outElastic(double time);
double inOutElastic(double time);
double inBounce(double time);
double outBounce(double time);
double inOutBounce(double time);
double inSine(double time);
double outSine(double time);
double inOutSine(double time);
double inQuad(double time);
double outQuad(double time);
double inOutQuad(double time);
double inCubic(double time);
double outCubic(double time);
double inOutCubic(double time);
double inQuart(double time);
double outQuart(double time);
double inOutQuart(double time);
double inQuint(double time);
double outQuint(double time);
double inOutQuint(double time);
double inExpo(double time);
double outExpo(double time);
double inOutExpo(double time);
double inOutExpo(double time);
double inCirc(double time);
double outCirc(double time);
double inOutCirc(double time);
double inBack(double time);
double outBack(double time);
double inOutBack(double time);
double inElastic(double time);
double outElastic(double time);
double inOutElastic(double time);
double inBounce(double time);
double outBounce(double time);
double inOutBounce(double time);
}

View File

@ -1,49 +1,50 @@
#pragma once
#include "utils/RaylibDeprecated.hpp"
#include <cmath>
#include <raylib.h>
#include "utils/RaylibDeprecated.hpp"
class GridMap
{
public:
GridMap()
{
Image image = GenImageColor(100, 100, WHITE);
ImageDrawLine(&image, image.width*0.5f, 0, image.width*0.5f, image.height, {0, 0, 0, 120});
ImageDrawLine(&image, 0, image.height*0.5f, 100, image.height*0.5f, {0, 0, 0, 120});
ImageDrawRectangleLines(&image, {0.0f, 0.0f, image.width - 2.0f, image.height - 2.0f}, 2, {0, 0, 0, 180});
GridMap()
{
Image image = GenImageColor(100, 100, WHITE);
ImageDrawLine(&image, image.width*0.5f, 0, image.width*0.5f, image.height, {0, 0, 0, 120});
ImageDrawLine(&image, 0, image.height*0.5f, 100, image.height*0.5f, {0, 0, 0, 120});
ImageDrawRectangleLines(&image, {0.0f, 0.0f, image.width - 2.0f, image.height - 2.0f}, 2, {0, 0, 0, 180});
texture = LoadTextureFromImage(image);
UnloadImage(image);
}
texture = LoadTextureFromImage(image);
UnloadImage(image);
}
~GridMap()
{
UnloadTexture(texture);
}
~GridMap()
{
UnloadTexture(texture);
}
void Draw(Camera2D camera)
{
Vector2 topLeft = GetScreenToWorld2D({0.0f, 0.0f}, camera);
Vector2 botRight = GetScreenToWorld2D({(float)GetScreenWidth(), (float)GetScreenHeight()}, camera);
void Draw(Camera2D camera)
{
Vector2 topLeft = GetScreenToWorld2D({0.0f, 0.0f}, camera);
Vector2 botRight = GetScreenToWorld2D({(float)GetScreenWidth(), (float)GetScreenHeight()}, camera);
float SWidth = (std::ceil((botRight.x-topLeft.x) / texture.width) + 1) * texture.width;
float SHeight = (std::ceil((botRight.y-topLeft.y) / texture.height) + 1) * texture.height;
float SWidth = (std::ceil((botRight.x-topLeft.x) / texture.width) + 1) * texture.width;
float SHeight = (std::ceil((botRight.y-topLeft.y) / texture.height) + 1) * texture.height;
float SX = (std::ceil(topLeft.x / texture.width) - 1) * texture.width;
float SY = (std::ceil(topLeft.y / texture.height) - 1) * texture.height;
float SX = (std::ceil(topLeft.x / texture.width) - 1) * texture.width;
float SY = (std::ceil(topLeft.y / texture.height) - 1) * texture.height;
DrawTextureTiled(
texture,
{0.0f, 0.0f, (float)texture.width, (float)texture.height},
{SX, SY, SWidth, SHeight},
// {topLeft.x, topLeft.y, botRight.x-topLeft.x, botRight.y-topLeft.y},
{0.0f, 0.0f}, 0.0f, 1.0f, WHITE
);
}
DrawTextureTiled(
texture,
{0.0f, 0.0f, (float)texture.width, (float)texture.height},
{SX, SY, SWidth, SHeight},
// {topLeft.x, topLeft.y, botRight.x-topLeft.x, botRight.y-topLeft.y},
{0.0f, 0.0f}, 0.0f, 1.0f, WHITE
);
}
private:
Texture2D texture;
Texture2D texture;
};

66
src/utils/Matrix.cpp Normal file
View File

@ -0,0 +1,66 @@
#include <cmath>
#include "Panda.hpp"
namespace panda {
void Matrix::identity()
{
a = 1.0f;
b = 0.0f;
c = 0.0f;
d = 1.0f;
tx = 0.0f;
ty = 0.0f;
}
void Matrix::translate(float dx, float dy)
{
Matrix m;
m.tx = dx;
m.ty = dy;
concat(m);
}
void Matrix::rotate(float radian)
{
float cos = std::cos(radian);
float sin = std::sin(radian);
float a1 = a * cos - b * sin;
b = a * sin + b * cos;
a = a1;
float c1 = c * cos - d * sin;
d = c * sin + d * cos;
c = c1;
float tx1 = tx * cos - ty * sin;
ty = tx * sin + ty * cos;
tx = tx1;
}
void Matrix::scale(float sx, float sy)
{
a *= sx;
b *= sy;
c *= sx;
d *= sy;
tx *= sx;
ty *= sy;
}
void Matrix::concat(Matrix m)
{
float a1 = a * m.a + b * m.c;
b = a * m.b + b * m.d;
a = a1;
float c1 = c * m.a + d * m.c;
d = c * m.b + d * m.d;
c = c1;
float tx1 = tx * m.a + ty * m.c + m.tx;
ty = tx * m.b + ty * m.d + m.ty;
tx = tx1;
}
}

View File

@ -1,5 +1,6 @@
#pragma once
#include <cstddef>
#include <list>
#include <vector>
#include <functional>
@ -9,70 +10,94 @@
namespace panda
{
// template<typename T>
// class Pool
// {
// public:
// Pool(int size) : container(size) { }
// template<typename T>
// class Pool
// {
// public:
// Pool(int size) : container(size) { }
// T &get()
// {
// if (activeIndex != container.size())
// {
// activeIndex++;
// return container[activeIndex-1];
// }
// else
// {
// if (custom)
// {
// return container[custom()];
// }
// else
// {
// int r = Random::getInstance().UNI() * (container.size()-1);
// return container[r];
// }
// }
// }
// T &get()
// {
// if (activeIndex != container.size())
// {
// activeIndex++;
// return container[activeIndex-1];
// }
// else
// {
// if (custom)
// {
// return container[custom()];
// }
// else
// {
// int r = Random::getInstance().UNI() * (container.size()-1);
// return container[r];
// }
// }
// }
// void put(int index)
// {
// activeIndex--;
// std::swap(container[activeIndex], container[index]);
// }
// void put(int index)
// {
// activeIndex--;
// std::swap(container[activeIndex], container[index]);
// }
// // int countActive() { return activeIndex; }
// int activeIndex;
// std::vector<T> container;
// std::function<int()> custom;
// };
// // int countActive() { return activeIndex; }
// int activeIndex;
// std::vector<T> container;
// std::function<int()> custom;
// };
template<typename T>
class PoolPointer {
private:
std::list<T*> free;
template<typename T, size_t SIZE>
class PoolPointer {
private:
std::list<T*> free;
public:
PoolPointer() : free() { }
public:
PoolPointer() : free()
{
for (size_t i=0; i<SIZE; i++) free.emplace_back(new T());
}
T* get() {
if (free.empty())
return new T(); // no objects are free
// get the last object in the list
auto obj = free.back();
free.pop_back();
return obj;
}
T* get() {
if (free.empty())
return new T(); // no objects are free
// get the last object in the list
auto obj = free.back();
free.pop_back();
return obj;
}
int getFreeSize()
{
return free.size();
}
int getFreeSize()
{
return free.size();
}
/// Mark the given object for reuse in the future.
inline void put(T* obj) { free.emplace_back(obj); }
};
/// Mark the given object for reuse in the future.
inline void put(T* obj) { free.emplace_back(obj); }
};
template<typename T, size_t SIZE>
class PoolCircular {
public:
T pool[SIZE];
PoolCircular() :
head(0)
{ }
T *Get()
{
head = (head + 1) % SIZE;
return pool[head];
}
size_t size() { return SIZE; }
int getHead() { return head; } // for debug only!!!
private:
int head;
};
}

View File

@ -1,5 +1,7 @@
#include "utils/Random.hpp"
#include <chrono>
#include <cmath>
#include "utils/Random.hpp"
panda::Random::Random(uint32_t _w, uint32_t _z) {
m_w = _w;
@ -34,6 +36,13 @@ float panda::Random::range(float min, float max) {
return min + (max-min) * UNI();
}
float panda::Random::rangeEx(float min, float max, float lamda) {
const float u = UNI();
return min + (max-min) * std::pow(u, lamda);
}
float panda::Random::xorshift_uni(uint32_t x) {
return xorshift(x) * inv_uni;
}

View File

@ -19,6 +19,7 @@ namespace panda
uint32_t MWC();
float UNI();
float range(float min, float max);
float rangeEx(float min, float max, float lamda);
float xorshift_uni(uint32_t x);
float xorshift64_uni(uint64_t x);

View File

@ -1,85 +1,87 @@
#include "utils/RaylibDeprecated.hpp"
#include <raylib.h>
#include "Panda.hpp"
// Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest.
void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint)
void DrawTextureTiled(Texture texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint)
{
if ((texture.id <= 0) || (scale <= 0.0f)) return; // Wanna see a infinite loop?!...just delete this line!
if ((source.width == 0) || (source.height == 0)) return;
if ((texture.id <= 0) || (scale <= 0.0f)) return; // Wanna see a infinite loop?!...just delete this line!
if ((source.width == 0) || (source.height == 0)) return;
int tileWidth = (int)(source.width*scale), tileHeight = (int)(source.height*scale);
if ((dest.width < tileWidth) && (dest.height < tileHeight))
int tileWidth = (int)(source.width*scale), tileHeight = (int)(source.height*scale);
if ((dest.width < tileWidth) && (dest.height < tileHeight))
{
// Can fit only one tile
DrawTexturePro(texture, {source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
{dest.x, dest.y, dest.width, dest.height}, origin, rotation, tint);
}
else if (dest.width <= tileWidth)
{
// Tiled vertically (one column)
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
// Can fit only one tile
DrawTexturePro(texture, {source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
{dest.x, dest.y, dest.width, dest.height}, origin, rotation, tint);
DrawTexturePro(texture, {source.x, source.y, ((float)dest.width/tileWidth)*source.width, source.height}, {dest.x, dest.y + dy, dest.width, (float)tileHeight}, origin, rotation, tint);
}
else if (dest.width <= tileWidth)
// Fit last tile
if (dy < dest.height)
{
// Tiled vertically (one column)
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, {source.x, source.y, ((float)dest.width/tileWidth)*source.width, source.height}, {dest.x, dest.y + dy, dest.width, (float)tileHeight}, origin, rotation, tint);
}
// Fit last tile
if (dy < dest.height)
{
DrawTexturePro(texture, {source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
{dest.x, dest.y + dy, dest.width, dest.height - dy}, origin, rotation, tint);
}
DrawTexturePro(texture, {source.x, source.y, ((float)dest.width/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
{dest.x, dest.y + dy, dest.width, dest.height - dy}, origin, rotation, tint);
}
else if (dest.height <= tileHeight)
}
else if (dest.height <= tileHeight)
{
// Tiled horizontally (one row)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
// Tiled horizontally (one row)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
DrawTexturePro(texture, {source.x, source.y, source.width, ((float)dest.height/tileHeight)*source.height}, {dest.x + dx, dest.y, (float)tileWidth, dest.height}, origin, rotation, tint);
}
// Fit last tile
if (dx < dest.width)
{
DrawTexturePro(texture, {source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
{dest.x + dx, dest.y, dest.width - dx, dest.height}, origin, rotation, tint);
}
DrawTexturePro(texture, {source.x, source.y, source.width, ((float)dest.height/tileHeight)*source.height}, {dest.x + dx, dest.y, (float)tileWidth, dest.height}, origin, rotation, tint);
}
else
// Fit last tile
if (dx < dest.width)
{
// Tiled both horizontally and vertically (rows and columns)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, source, {dest.x + dx, dest.y + dy, (float)tileWidth, (float)tileHeight}, origin, rotation, tint);
}
if (dy < dest.height)
{
DrawTexturePro(texture, {source.x, source.y, source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
{dest.x + dx, dest.y + dy, (float)tileWidth, dest.height - dy}, origin, rotation, tint);
}
}
// Fit last column of tiles
if (dx < dest.width)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, {source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, source.height},
{dest.x + dx, dest.y + dy, dest.width - dx, (float)tileHeight}, origin, rotation, tint);
}
// Draw final tile in the bottom right corner
if (dy < dest.height)
{
DrawTexturePro(texture, {source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
{dest.x + dx, dest.y + dy, dest.width - dx, dest.height - dy}, origin, rotation, tint);
}
}
DrawTexturePro(texture, {source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)dest.height/tileHeight)*source.height},
{dest.x + dx, dest.y, dest.width - dx, dest.height}, origin, rotation, tint);
}
}
else
{
// Tiled both horizontally and vertically (rows and columns)
int dx = 0;
for (;dx+tileWidth < dest.width; dx += tileWidth)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, source, {dest.x + dx, dest.y + dy, (float)tileWidth, (float)tileHeight}, origin, rotation, tint);
}
if (dy < dest.height)
{
DrawTexturePro(texture, {source.x, source.y, source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
{dest.x + dx, dest.y + dy, (float)tileWidth, dest.height - dy}, origin, rotation, tint);
}
}
// Fit last column of tiles
if (dx < dest.width)
{
int dy = 0;
for (;dy+tileHeight < dest.height; dy += tileHeight)
{
DrawTexturePro(texture, {source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, source.height},
{dest.x + dx, dest.y + dy, dest.width - dx, (float)tileHeight}, origin, rotation, tint);
}
// Draw final tile in the bottom right corner
if (dy < dest.height)
{
DrawTexturePro(texture, {source.x, source.y, ((float)(dest.width - dx)/tileWidth)*source.width, ((float)(dest.height - dy)/tileHeight)*source.height},
{dest.x + dx, dest.y + dy, dest.width - dx, dest.height - dy}, origin, rotation, tint);
}
}
}
}

View File

@ -1,4 +0,0 @@
#pragma once
#include <raylib.h>
void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint);

View File

@ -2,15 +2,15 @@
#include <inicpp.h>
#include <raylib.h>
#include "core/Panda.hpp"
#include "Panda.hpp"
namespace
{
struct TextureAtlas
{
Texture2D texture;
std::unordered_map<std::string, panda::TextureAtlasItem> items;
};
struct TextureAtlas
{
Texture2D texture;
std::unordered_map<std::string, panda::TextureAtlasItem> items;
};
}
static std::unordered_map<std::string, TextureAtlas> TextureAtlasMap;
@ -18,64 +18,64 @@ static std::unordered_map<std::string, TextureAtlas> TextureAtlasMap;
bool panda::LoadTextureAtlas(const char *image_path, const char *ini_path, std::string AtlasKey)
{
ini::IniFile ini;
TextureAtlas atlas;
ini::IniFile ini;
TextureAtlas atlas;
char* text = LoadFileText(ini_path);
ini.decode(text);
char* text = LoadFileText(ini_path);
ini.decode(text);
// load texture
atlas.texture = LoadTexture(image_path);
// load texture
atlas.texture = LoadTexture(image_path);
// loop item
std::stringstream ss(ini["meta"]["list"].as<const char*>());
std::string item;
while (std::getline(ss, item, ';')) {
atlas.items.insert({item, TextureAtlasItem{
ini[item]["x"].as<int>(),
ini[item]["y"].as<int>(),
ini[item]["w"].as<int>(),
ini[item]["h"].as<int>(),
ini[item]["px"].as<float>(),
ini[item]["py"].as<float>(),
}});
}
// loop item
std::stringstream ss(ini["meta"]["list"].as<const char*>());
std::string item;
while (std::getline(ss, item, ';')) {
atlas.items.insert({item, TextureAtlasItem{
ini[item]["x"].as<int>(),
ini[item]["y"].as<int>(),
ini[item]["w"].as<int>(),
ini[item]["h"].as<int>(),
ini[item]["px"].as<float>(),
ini[item]["py"].as<float>(),
}});
}
UnloadFileText(text);
UnloadFileText(text);
TextureAtlasMap.insert({AtlasKey, atlas});
return true;
TextureAtlasMap.insert({AtlasKey, atlas});
return true;
}
bool panda::UnloadTextureAtlas(std::string AtlasKey)
{
// looks like its already clear automatically (when close window)
// just incase if it not when changing scene
if (TextureAtlasMap.count(AtlasKey))
{
TextureAtlas &atlas = TextureAtlasMap.at(AtlasKey);
UnloadTexture(atlas.texture);
TextureAtlasMap.erase(AtlasKey);
}
return true;
// looks like its already clear automatically (when close window)
// just incase if it not when changing scene
if (TextureAtlasMap.count(AtlasKey))
{
TextureAtlas &atlas = TextureAtlasMap.at(AtlasKey);
UnloadTexture(atlas.texture);
TextureAtlasMap.erase(AtlasKey);
}
return true;
}
void panda::DrawTextureAtlas(std::string AtlasKey, std::string key, int x, int y)
{
DrawTextureAtlasPro(AtlasKey, key, x, y, WHITE);
DrawTextureAtlasPro(AtlasKey, key, x, y, WHITE);
}
void panda::DrawTextureAtlasPro(std::string AtlasKey, std::string key, int x, int y, Color color, bool flipX, bool flipY)
{
TextureAtlas &atlas = TextureAtlasMap.at(AtlasKey);
TextureAtlasItem &item = atlas.items.at(key);
TextureAtlas &atlas = TextureAtlasMap.at(AtlasKey);
TextureAtlasItem &item = atlas.items.at(key);
float _flipX = (flipX) ? -1.0f : 1.0f;
float _flipY = (flipY) ? -1.0f : 1.0f;
float _flipX = (flipX) ? -1.0f : 1.0f;
float _flipY = (flipY) ? -1.0f : 1.0f;
// todo flip position
DrawTextureRec(
atlas.texture,
{(float)item.x, (float)item.y, item.w*_flipX, item.h*_flipY},
{x - item.px*item.w, y - item.py*item.h}, color);
// todo flip position
DrawTextureRec(
atlas.texture,
{(float)item.x, (float)item.y, item.w*_flipX, item.h*_flipY},
{x - item.px*item.w, y - item.py*item.h}, color);
}