summaryrefslogtreecommitdiff
path: root/src/FLD.hpp
blob: 05677fb893d79ee2fd33d4e78811a24a503e8f00 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#pragma once
#include <SDL2/SDL_render.h>
#include <string>
#include <map>
#include <optional>
#include <climits>
#include "soloud.h"

#define READONLY(T, X, V) private: T _##X = V; public: decltype(_##X) const& X = _##X

class FLD {
public:
	using Error = int;
	using Uint = unsigned int;
	using MainLoop = int (*)(FLD& fld, void *udata);
	struct Config {
		int width = 640;
		int height = 480;
		int scale = 1;
		int target_fps = 60;
		bool pixel_perfect = true;
		bool hide_cursor = true;
		std::string title = "FLD project";
	};
	struct Color {
		float r = -1.0f;
		float g = -1.0f;
		float b = -1.0f;
		float a = -1.0f;
	};
	struct Point {
		int x;
		int y;
	};
	struct Rectangle {
		int x;
		int y;
		int w;
		int h;
	};
	struct DrawImageOpts {
		const Point& p;
		int ix = 0;
		int iy = 0;
		int w = INT_MIN;
		int h = INT_MIN;
		float r = 0.0f;
		float sx = 1.0f;
		float sy = 1.0f;
		Uint f = NONE;
	};
	struct Image {
		FLD *fld = nullptr;
		std::string path = "";
		bool valid = true;
		SDL_Texture *ptr = nullptr;
		int width = 0;
		int height = 0;

		[[nodiscard]] Error invalid() const;
		Error draw(const DrawImageOpts& opts) const;
		Error setScaleMode(SDL_ScaleMode scale_mode) const;
	};
	enum DrawFlag {
		NONE = 0,
		FILL = 1,
		CENTER = 2,
		FLIP_X = 4,
		FLIP_Y = 8,
	};
	static constexpr Color BLACK {0.0f, 0.0f, 0.0f, -1.0f};
	static constexpr Color RED {1.0f, 0.0f, 0.0f, -1.0f};
	static constexpr Color GREEN {0.0f, 1.0f, 0.0f, -1.0f};
	static constexpr Color BLUE {0.0f, 0.0f, 1.0f, -1.0f};
	static constexpr Color YELLOW {1.0f, 1.0f, 0.0f, -1.0f};
	static constexpr Color PURPLE {1.0f, 0.0f, 1.0f, -1.0f};
	static constexpr Color CYAN {0.0f, 1.0f, 1.0f, -1.0f};
	static constexpr Color WHITE {1.0f, 1.0f, 1.0f, -1.0f};
	Point viewport = {0, 0};

	const Config config;
	SoLoud::Soloud soloud = {};
	READONLY(SDL_Window *, window, nullptr);
	READONLY(SDL_Renderer *, renderer, nullptr);
	READONLY(SDL_Texture *, target, nullptr);
	READONLY(unsigned long, tick, 0);
	READONLY(Color, drawColor, Color({0, 0, 0, 1}));
public:
	FLD(const Config& config);
	FLD(const Config&& config);
	~FLD();

	[[nodiscard]] Error init();
	[[nodiscard]] Error init(MainLoop main_loop, void *udata=nullptr);
	void run(MainLoop main_loop, void *udata = nullptr);

	[[nodiscard]] Error drawBegin() const;
	[[nodiscard]] Error drawEnd();
	Error drawSetColor(const Color& c);
	Error drawClear() const;
	Error drawPoint(const Point& p) const;
	Error drawLine(const Point& p0, const Point& p1) const;
	Error drawRectangle(const Rectangle& rect, Uint flags=NONE) const;

	[[nodiscard]] Image& image(const std::string& path);
private:
	bool shouldQuit = false;
	struct {
		bool managed = false;
		Uint64 min_dt;
		Uint64 next_time;
	} fps;
	struct {
		float scale = 1.0;
		int off_x = 0;
		int off_y = 0;
	} transform;
	std::map<const std::string, Image> images = {};

	Error sdlError(const std::string& msg="") const;
	Error soloudError(SoLoud::result result) const;
	[[nodiscard]] Error initBasepath() const;
	[[nodiscard]] Error initWindow();
	[[nodiscard]] Error initRenderer();
	[[nodiscard]] Error initTarget();
	[[nodiscard]] Error initSoloud();
	void cycleEvents();
};