Screenshot support, another example added
[taruga.git] / include / taruga.hpp
blob8bff8b22f7d3e3139348b6e9a186fc66071e1e45
1 /*
2 * libstring
3 * https://github.com/vrmiguel/taruga
5 * Copyright (c) 2020 Vinícius R. Miguel
6 * <vinicius.miguel at unifesp.br>
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in all
16 * copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
27 #ifndef __TARUGA_MAIN_HPP
28 #define __TARUGA_MAIN_HPP
30 #include <SFML/Graphics/RenderWindow.hpp>
31 #include <SFML/Graphics/Sprite.hpp>
32 #include <SFML/Graphics/Texture.hpp>
33 #include <SFML/Window/Event.hpp>
35 #include <cmath>
36 #include <queue>
38 //! TODO:
39 //! Decide whether or not to include a second built-in icon
40 //! Make sure lines before drawn are still drawn once the pen goes up. (That is, old ones remains, but no new ones come up)
41 //! ?? Test more
43 //! Holds a 32x32 PNG cute turtle icon
44 static const uint8_t __turtle_png[1479] = {
45 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
46 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20,
47 0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, 0xc6, 0x00, 0x00, 0x00,
48 0x03, 0x73, 0x42, 0x49, 0x54, 0x08, 0x08, 0x08, 0xdb, 0xe1, 0x4f, 0xe0,
49 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0xdd,
50 0x00, 0x00, 0x00, 0xdd, 0x01, 0x70, 0x53, 0xa2, 0x07, 0x00, 0x00, 0x00,
51 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72,
52 0x65, 0x00, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61,
53 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x00, 0x00,
54 0x02, 0x8b, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x00, 0x80, 0x80,
55 0x00, 0x80, 0x80, 0x40, 0xff, 0x80, 0x4d, 0xe6, 0x66, 0xb3, 0xe6, 0x33,
56 0x5d, 0xe8, 0x5d, 0xb9, 0xe8, 0x2e, 0x4e, 0xeb, 0x62, 0xb1, 0xd8, 0x3b,
57 0x5b, 0xdb, 0x5b, 0xb6, 0xdb, 0x37, 0xbb, 0xdd, 0x33, 0xb8, 0xe3, 0x39,
58 0x00, 0xaa, 0x61, 0x55, 0xe7, 0x61, 0x55, 0xdf, 0x60, 0x00, 0xad, 0x5b,
59 0x84, 0xe5, 0x46, 0xbc, 0xda, 0x3c, 0x55, 0xe5, 0x62, 0xb7, 0xde, 0x3b,
60 0x00, 0x9f, 0x59, 0xb9, 0xdf, 0x39, 0xb6, 0xdb, 0x37, 0x51, 0xe2, 0x63,
61 0x53, 0xe3, 0x5e, 0xb7, 0xde, 0x37, 0x00, 0xa4, 0x57, 0xb7, 0xdd, 0x3a,
62 0x55, 0xe3, 0x5e, 0x55, 0xe3, 0x61, 0xba, 0xdf, 0x39, 0x52, 0xe4, 0x5e,
63 0x55, 0xe4, 0x61, 0xb9, 0xdc, 0x3a, 0xb8, 0xdd, 0x38, 0xba, 0xde, 0x3a,
64 0x53, 0xe2, 0x61, 0xbb, 0xdf, 0x39, 0x55, 0xe3, 0x60, 0x83, 0xe0, 0x4f,
65 0x00, 0xab, 0x5e, 0x81, 0xde, 0x4c, 0xb9, 0xde, 0x38, 0x0a, 0xae, 0x5a,
66 0x53, 0xe4, 0x5f, 0xba, 0xde, 0x3a, 0x00, 0xaa, 0x5d, 0x54, 0xe4, 0x5f,
67 0x55, 0xe2, 0x60, 0xba, 0xdc, 0x38, 0xb8, 0xde, 0x3a, 0xb9, 0xdd, 0x3a,
68 0xb8, 0xdd, 0x39, 0x00, 0xa0, 0x59, 0x7d, 0xe0, 0x50, 0x02, 0xa2, 0x59,
69 0x53, 0xe3, 0x60, 0xb8, 0xdd, 0x39, 0x54, 0xe3, 0x60, 0xb9, 0xde, 0x3a,
70 0x15, 0x9a, 0x4a, 0x00, 0x9f, 0x57, 0x53, 0xe3, 0x61, 0xb9, 0xde, 0x39,
71 0x00, 0xab, 0x5e, 0x54, 0xe2, 0x60, 0x79, 0xe1, 0x52, 0x54, 0xe3, 0x60,
72 0xb9, 0xdd, 0x3a, 0x00, 0xab, 0x5f, 0xb9, 0xdd, 0x39, 0x55, 0xe3, 0x60,
73 0x54, 0xe3, 0x60, 0xba, 0xdd, 0x39, 0x77, 0xe0, 0x52, 0xb9, 0xdd, 0x39,
74 0xb9, 0xde, 0x39, 0x54, 0xe3, 0x5f, 0x00, 0xab, 0x5f, 0xba, 0xde, 0x39,
75 0xb9, 0xdd, 0x39, 0x55, 0xe3, 0x60, 0x54, 0xe3, 0x60, 0xba, 0xdd, 0x39,
76 0x04, 0x8a, 0x46, 0x31, 0xc8, 0x5e, 0x8e, 0xd1, 0x43, 0x55, 0xe3, 0x60,
77 0xb9, 0xdd, 0x38, 0x55, 0xe3, 0x5f, 0xb9, 0xdd, 0x39, 0xb9, 0xdc, 0x39,
78 0x54, 0xe3, 0x60, 0x00, 0x9e, 0x57, 0x54, 0xe3, 0x60, 0xb9, 0xdd, 0x39,
79 0x54, 0xe3, 0x5f, 0xb9, 0xdd, 0x39, 0x53, 0xe3, 0x60, 0xb9, 0xdd, 0x39,
80 0x00, 0xab, 0x5e, 0x00, 0x9d, 0x56, 0x00, 0xa2, 0x57, 0x54, 0xe3, 0x60,
81 0x00, 0x96, 0x50, 0x3c, 0xbb, 0x52, 0xb9, 0xdd, 0x39, 0x00, 0x9d, 0x56,
82 0x2c, 0xb7, 0x55, 0x54, 0xe3, 0x60, 0x69, 0xe2, 0x59, 0x54, 0xe3, 0x60,
83 0x54, 0xe3, 0x60, 0xb9, 0xdd, 0x39, 0xb9, 0xdd, 0x39, 0x0a, 0xa6, 0x58,
84 0x54, 0xe3, 0x60, 0xb9, 0xdd, 0x39, 0x00, 0x9b, 0x55, 0x54, 0xe3, 0x5f,
85 0xb9, 0xdd, 0x39, 0xb9, 0xdd, 0x39, 0x00, 0x83, 0x44, 0x00, 0x8e, 0x4c,
86 0x0f, 0xa5, 0x55, 0x54, 0xe3, 0x60, 0xb9, 0xdd, 0x39, 0x00, 0x82, 0x41,
87 0x03, 0x98, 0x50, 0x08, 0xa3, 0x56, 0x0d, 0x98, 0x4b, 0x4a, 0xb2, 0x46,
88 0x54, 0xe3, 0x60, 0xb9, 0xdd, 0x39, 0x00, 0x75, 0x39, 0x00, 0x76, 0x39,
89 0x00, 0x76, 0x3a, 0x00, 0x77, 0x3a, 0x00, 0x78, 0x3b, 0x00, 0x79, 0x3c,
90 0x00, 0x7b, 0x3e, 0x00, 0x7c, 0x3e, 0x00, 0x7d, 0x3f, 0x00, 0x7e, 0x3f,
91 0x00, 0x7f, 0x40, 0x00, 0x80, 0x41, 0x00, 0x81, 0x41, 0x00, 0x81, 0x42,
92 0x00, 0x82, 0x42, 0x00, 0x82, 0x43, 0x00, 0x83, 0x43, 0x00, 0x85, 0x44,
93 0x00, 0x85, 0x45, 0x00, 0x87, 0x45, 0x00, 0x87, 0x46, 0x00, 0x88, 0x46,
94 0x00, 0x88, 0x47, 0x00, 0x89, 0x47, 0x00, 0x8d, 0x4b, 0x00, 0x8e, 0x4a,
95 0x00, 0x8e, 0x4b, 0x00, 0x8f, 0x4b, 0x00, 0x90, 0x4b, 0x00, 0x90, 0x4c,
96 0x00, 0x91, 0x4c, 0x00, 0x94, 0x4e, 0x00, 0x95, 0x4f, 0x00, 0x96, 0x50,
97 0x00, 0x96, 0x52, 0x00, 0x97, 0x52, 0x00, 0x99, 0x52, 0x00, 0x99, 0x54,
98 0x00, 0x9a, 0x53, 0x00, 0x9a, 0x54, 0x00, 0x9c, 0x54, 0x00, 0x9d, 0x55,
99 0x00, 0xa2, 0x58, 0x00, 0xa9, 0x5d, 0x00, 0xaa, 0x5d, 0x00, 0xaa, 0x5e,
100 0x00, 0xab, 0x5e, 0x01, 0x8f, 0x4c, 0x01, 0x9b, 0x55, 0x01, 0xab, 0x5e,
101 0x02, 0x9d, 0x56, 0x03, 0x85, 0x43, 0x06, 0xac, 0x5d, 0x07, 0xa3, 0x57,
102 0x09, 0xa5, 0x58, 0x0c, 0xa8, 0x58, 0x12, 0xb0, 0x5a, 0x14, 0xaf, 0x59,
103 0x1e, 0xb3, 0x58, 0x2b, 0xb8, 0x54, 0x2d, 0xc4, 0x5c, 0x37, 0xba, 0x53,
104 0x3c, 0xbb, 0x52, 0x3f, 0xcc, 0x5b, 0x3f, 0xd3, 0x5e, 0x40, 0xd3, 0x5e,
105 0x42, 0xbd, 0x51, 0x4b, 0xdc, 0x5f, 0x50, 0xe0, 0x60, 0x54, 0xe3, 0x60,
106 0x56, 0xe3, 0x5f, 0x57, 0xe3, 0x5f, 0x5a, 0xc3, 0x4c, 0x85, 0xc8, 0x3f,
107 0x88, 0xd0, 0x43, 0x9c, 0xd2, 0x3c, 0xa0, 0xd6, 0x3e, 0xa1, 0xd7, 0x3e,
108 0xaf, 0xda, 0x3b, 0xb5, 0xdc, 0x3a, 0xb9, 0xdd, 0x39, 0x36, 0xf4, 0x4c,
109 0x4d, 0x00, 0x00, 0x00, 0x88, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x02, 0x04,
110 0x04, 0x0a, 0x0a, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x12, 0x15,
111 0x15, 0x18, 0x1c, 0x1d, 0x22, 0x27, 0x27, 0x28, 0x28, 0x2a, 0x2c, 0x2e,
112 0x2e, 0x35, 0x35, 0x36, 0x3f, 0x3f, 0x41, 0x42, 0x42, 0x44, 0x46, 0x47,
113 0x47, 0x48, 0x4a, 0x4c, 0x4d, 0x4d, 0x4f, 0x56, 0x5c, 0x5d, 0x5e, 0x60,
114 0x60, 0x65, 0x6a, 0x70, 0x81, 0x83, 0x84, 0x90, 0x90, 0x92, 0x92, 0x95,
115 0x98, 0x99, 0x99, 0x9e, 0xa0, 0xa2, 0xa4, 0xa4, 0xaa, 0xaa, 0xac, 0xad,
116 0xad, 0xaf, 0xaf, 0xb0, 0xb3, 0xba, 0xbf, 0xc1, 0xc7, 0xc9, 0xca, 0xcc,
117 0xcf, 0xcf, 0xd0, 0xd0, 0xd3, 0xd3, 0xd6, 0xd8, 0xda, 0xda, 0xda, 0xdb,
118 0xdb, 0xdc, 0xdc, 0xe0, 0xe3, 0xe4, 0xe9, 0xea, 0xea, 0xea, 0xec, 0xed,
119 0xef, 0xef, 0xf0, 0xf1, 0xf6, 0xf7, 0xf8, 0xf9, 0xf9, 0xfb, 0xfb, 0xfb,
120 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
121 0xfe, 0xa7, 0x5c, 0x18, 0x53, 0x00, 0x00, 0x02, 0x1a, 0x49, 0x44, 0x41,
122 0x54, 0x38, 0x4f, 0x75, 0xd2, 0xf9, 0x5b, 0x4c, 0x51, 0x18, 0x07, 0xf0,
123 0x83, 0x92, 0x7d, 0x27, 0x4a, 0x52, 0x76, 0x22, 0x6b, 0xb6, 0x42, 0x28,
124 0xfb, 0xbe, 0x65, 0x5f, 0xb2, 0xef, 0x2d, 0x84, 0xca, 0x56, 0x38, 0xd3,
125 0x36, 0x39, 0x97, 0x21, 0xc2, 0xd4, 0x84, 0x19, 0x1c, 0x14, 0x4d, 0x0a,
126 0x65, 0xdf, 0x8f, 0x25, 0xe1, 0xfc, 0x39, 0xce, 0x7b, 0xce, 0xdc, 0x99,
127 0x3b, 0xcf, 0xd3, 0xfd, 0xfe, 0x30, 0xcf, 0x7d, 0xe6, 0xfb, 0x99, 0x3b,
128 0xe7, 0x7d, 0xef, 0x45, 0xc8, 0x98, 0x18, 0xce, 0x19, 0x5b, 0x88, 0x4c,
129 0xd3, 0x3b, 0x1d, 0xc0, 0x8f, 0x11, 0xa6, 0x60, 0x19, 0x07, 0xc0, 0x0e,
130 0x9b, 0xf5, 0xc1, 0x5c, 0x01, 0x36, 0xcc, 0x04, 0xc4, 0xe8, 0xc0, 0xec,
131 0x14, 0xe3, 0x75, 0x30, 0xdb, 0x04, 0x44, 0xe9, 0x60, 0x92, 0x09, 0xe8,
132 0x70, 0x82, 0xff, 0xfb, 0xf3, 0xf9, 0x1b, 0xfb, 0xde, 0xad, 0xf9, 0xbe,
133 0xc5, 0xf0, 0x83, 0xaf, 0x6a, 0xdd, 0x94, 0x3e, 0xcb, 0x99, 0xd8, 0xb2,
134 0x99, 0x3a, 0x70, 0xda, 0x6e, 0x37, 0x84, 0x42, 0xb2, 0x57, 0x07, 0xf8,
135 0xb7, 0xfd, 0x17, 0x6c, 0x3d, 0x47, 0x6c, 0x55, 0x3a, 0x28, 0xcf, 0xc3,
136 0xb9, 0x5b, 0xe6, 0x87, 0x7b, 0xeb, 0xa0, 0xb8, 0x0b, 0xbc, 0xe9, 0x85,
137 0x43, 0x09, 0xd5, 0x5b, 0x1f, 0x7d, 0x62, 0xe7, 0x63, 0x5b, 0xab, 0x3e,
138 0x74, 0x87, 0x38, 0xfc, 0x7b, 0x77, 0xb5, 0x12, 0xaa, 0xa7, 0xf4, 0xa5,
139 0x98, 0x66, 0x7b, 0x08, 0xf4, 0x6d, 0x93, 0x45, 0xdf, 0x28, 0x7e, 0x0b,
140 0xc2, 0xe1, 0xb0, 0x5a, 0x65, 0x4f, 0xe9, 0x3b, 0x21, 0xb6, 0xb5, 0x11,
141 0x20, 0x11, 0xa6, 0xff, 0x09, 0x7f, 0x5f, 0x7d, 0x9d, 0x10, 0x82, 0x31,
142 0x2e, 0x90, 0x07, 0x7d, 0x0d, 0x1b, 0x49, 0x40, 0x68, 0x08, 0xf4, 0xfc,
143 0x03, 0x80, 0x2a, 0xa2, 0x3d, 0x78, 0x78, 0xad, 0x04, 0xe3, 0x72, 0x00,
144 0xf5, 0x00, 0xd8, 0x60, 0x34, 0x55, 0x82, 0x37, 0x00, 0x6e, 0x91, 0xbb,
145 0x70, 0x06, 0x0d, 0x17, 0x02, 0xa8, 0x93, 0x60, 0x0a, 0x5a, 0x27, 0xc1,
146 0x59, 0x97, 0xcb, 0x75, 0x87, 0x5c, 0x7d, 0x02, 0xe0, 0x5e, 0x1e, 0xbe,
147 0x78, 0x45, 0x44, 0x82, 0xb5, 0x28, 0xf3, 0xf4, 0x86, 0xf8, 0x71, 0x3d,
148 0xcf, 0x10, 0x88, 0x53, 0x8d, 0x79, 0x19, 0x43, 0x2c, 0x3d, 0xc6, 0xce,
149 0x58, 0x7f, 0xea, 0x38, 0x1a, 0xd0, 0x1e, 0x46, 0xd9, 0xeb, 0x74, 0x3a,
150 0x6f, 0x93, 0x92, 0xa7, 0x00, 0xee, 0xe7, 0xe3, 0x62, 0x4d, 0xd3, 0xb2,
151 0xe0, 0xfb, 0x76, 0x91, 0x9e, 0x5d, 0xcd, 0x84, 0x33, 0xdc, 0x80, 0x5b,
152 0x50, 0x6a, 0x53, 0x63, 0x6c, 0x46, 0xc6, 0x8c, 0x56, 0x53, 0x5c, 0x7a,
153 0x5c, 0x79, 0xb3, 0xd4, 0x82, 0xed, 0x00, 0xa6, 0xfb, 0x81, 0xae, 0xf2,
154 0x41, 0x95, 0x1a, 0xf7, 0xd0, 0xd7, 0x0f, 0xa0, 0xa5, 0xa2, 0xaf, 0x20,
155 0xb6, 0xb2, 0xb2, 0xa2, 0x22, 0x0b, 0x2e, 0x16, 0xfd, 0x01, 0xff, 0x3e,
156 0x2c, 0xa9, 0x16, 0x7a, 0xf9, 0x2c, 0xec, 0x52, 0xac, 0xe9, 0x63, 0xec,
157 0xa3, 0xd2, 0xf8, 0x97, 0x0a, 0xef, 0xd3, 0x04, 0xd1, 0xc0, 0x52, 0x23,
158 0x7c, 0x7d, 0xf7, 0x34, 0xce, 0x7f, 0x3f, 0xf7, 0xbd, 0x0f, 0x76, 0x4b,
159 0xfe, 0x47, 0xc6, 0x0e, 0x75, 0xf1, 0x82, 0xc5, 0xb0, 0xcc, 0x5f, 0x27,
160 0x7d, 0x6f, 0x54, 0xcd, 0x5b, 0xd8, 0xe2, 0x2c, 0xbd, 0x0f, 0xca, 0x90,
161 0xeb, 0xfe, 0xbb, 0x4f, 0x07, 0x47, 0xbe, 0xca, 0x35, 0xa7, 0xb4, 0xf2,
162 0x80, 0x41, 0x5c, 0x65, 0xf9, 0xc8, 0x39, 0x3b, 0xdd, 0xf4, 0xd8, 0xae,
163 0xc9, 0x2b, 0x98, 0x4a, 0x3f, 0x0f, 0x98, 0xa0, 0xfa, 0x45, 0x1d, 0xc5,
164 0x75, 0xa7, 0x5e, 0xe2, 0xa3, 0xf3, 0x12, 0x05, 0xc6, 0x78, 0x40, 0xf4,
165 0xaa, 0xfd, 0x19, 0x1b, 0xe7, 0x0e, 0x44, 0x86, 0x0c, 0x9d, 0xb7, 0xe9,
166 0xe8, 0x9e, 0x95, 0xa3, 0xc4, 0xd5, 0x7f, 0xbc, 0x59, 0x87, 0x09, 0x1b,
167 0x60, 0xeb, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
168 0x42, 0x60, 0x82
171 namespace taruga
174 //! \brief The Icon enum lets the user decide between the built-in icons, Turtle and (TODO) Arrow
176 enum class Icon : bool {
177 Turtle,
178 Arrow,
182 //! \brief The Verbosity enum defines the different options for console output verbosity
185 typedef uint8_t u8;
187 enum class Verbosity : uint8_t {
188 Quiet = 1,
189 Verbose = 2,
190 VeryVerbose = 3,
191 Debug = 4
195 //! \brief The Instruction enum
197 enum class Instruction : uint8_t {
198 Rotate, //! Rotates the turtle by a given amount of degrees
199 Walk, //! Walks forwards (or backwards) by the given amount of units.
200 PenMovement, //! Puts the pen up or down.
201 LineChangeColor, //! Change the line color to something else
202 Screenshot, //! Screenshot of the current
203 //SpriteChangeColor, //! Change the icon color to something else
204 // Stamp, //! Permanently stamp the sprite at the current position and rotation
207 union ActionData {
208 float rot_angle; //! Used when rotating
209 int32_t walk_dist; //! Used when walking forwards or backwards
210 //sf::Vector2u next_pos; //! Used for teleports (sets the turtle directly in next_pos)
211 uint8_t next_color[3]; //! Used when changing icon color. Using an array here because sf::Color has non-trivial default constructor.
212 bool pen_down; //! Used when setting the pen up or down.
213 const char * filename;
217 //! \brief The Action struct
219 struct Action {
220 Instruction instr;
221 ActionData data;
222 Action(Instruction m_instr, ActionData m_data) : instr(m_instr), data(m_data) {};
226 //! brief The Line struct holds the starting and ending point of a line.
228 struct Line
230 float xi, yi, xf, yf;
231 sf::Color color;
232 Line(float _xi, float _yi) : xi(_xi), yi(_yi) {};
233 Line(float _xi, float _yi, float _xf, float _yf, sf::Color c) : xi(_xi), yi(_yi), xf(_xf), yf(_yf), color(c) {};
234 Line(float _xi, float _yi, sf::Color c) : xi(_xi), yi(_yi), color(c) {};
237 class Turtle{
238 private:
239 static constexpr float m_deg_to_rad = 3.14159265358979323846/180.0;
240 void init(); //! Initializes the variables with their default values
241 std::vector<Line> lines; //! All lines to be drawn.
242 sf::RenderWindow window; //! Window where the scene will be rendered
243 std::string title; //! The window's title
244 std::queue<Action> actions; //! The queue of actions that the turtle is going to do.
245 sf::Texture texture; //! The image to be used on the sprite. Kept in VRAM.
246 sf::Sprite sprite; //! The turtle's sprite.
247 sf::Color line_color; //! The current color of the line the turtle draws
248 bool m_pen_down; //! If the pen is up, the turtle will not draw while walking around
249 uint8_t walk_spd; //! Turtle's current velocity
250 float angle; //! Turtle's current heading angle in [0, 360)
251 float rot_vel; //! Turtle's rotational velocity
252 uint16_t width; //! Rendering window width
253 uint16_t height; //! Rendering window height
254 uint32_t x, y; //! Current positions
256 void _save_to_image(const char *); //! Save a screenshot
257 void _move_pen(bool); //! Sets the pen up or down
258 void _draw_line(Line); //! Draws the given line
259 void _draw_sprite(); //! Draws the sprite into the window
260 void _idle(); //! Keeps rendering a static scene. Runs when there are no more actions to do.
261 void _walk(int32_t); //! Internal logic for walking forward in the current heading angle
262 void _rotate(float); //! Internal logic for rotating by a given amount of degrees
263 void _draw_all_lines(bool clear_screen = true); //! Draws all saved lines
264 public:
265 Verbosity verbosity; //! Toggles verbose output on or off.
267 void set_window_title(const std::string& new_title);
268 Turtle() : width(800), height(600) { init(); }
269 Turtle(uint16_t _wth, uint16_t _hgt) : width(_wth), height(_hgt) { init(); }
270 Turtle(const sf::Vector2u p) : width(p.x), height(p.y) { init(); }
271 void save_to_image(const char *); //! Saves the current window view to an image with the given filename
272 void set_line_color(sf::Color); //! Sets the new color of the line the turtle will draw.
273 void set_line_color(u8, u8, u8); //! Sets the new color of the line the turtle will draw.
274 void set_line_color(u8[3]); //! Sets the new color of the line the turtle will draw.
275 void pen_up(); //! Sets the pen up so lines don't get drawn
276 void pen_down(); //! Sets the pen down so that the turtle draws a line wherever it walks
277 void set_icon(Icon); //! Allows to switch around between the two built-in icons: turtle or straight arrow.
278 void set_icon(sf::Texture); //! Allows for any image to be used as an icon. Do notice that Taruga won't scale the texture. If needed, use the Turtle::scale method.
279 void scale(float, float); //! Scales the turtle sprite
280 void forward(int32_t units); //! Walk forward the given amount of units.
281 void backwards(int32_t units); //! Walk backwards the given amount of units. The same as using forward() with a negative parameter.
282 void turn_right(float ang); //! Turns right by the specified amount of degrees.
283 void turn_left(float ang); //! Turns left by the specified amount of degrees.
284 //void dot(); //! Print a dot in the current position, even if the pen is up.
285 void draw_circle(); //! Draw a circle at the current position
286 void act(); //! Start moving the turtle. Will deplete the actions queue.
289 void Turtle::save_to_image(const char * _filename)
291 ActionData data; data.filename = _filename;
292 actions.push(Action(Instruction::Screenshot, data));
295 void Turtle::_save_to_image(const char * filename)
297 _draw_all_lines();
298 _draw_sprite();
299 sf::Vector2u window_size = window.getSize();
300 sf::Texture window_texture;
301 window_texture.create(window_size.x, window_size.y);
302 window_texture.update(window);
303 sf::Image screenshot = window_texture.copyToImage();
304 screenshot.saveToFile(filename);
308 void Turtle::_move_pen(bool m_pen_down)
310 ActionData data; data.pen_down = m_pen_down;
311 actions.push(Action(Instruction::PenMovement, data));
314 void Turtle::pen_up()
316 this->_move_pen(false);
319 void Turtle::pen_down()
321 this->_move_pen(true);
324 void Turtle::set_line_color(sf::Color color)
326 this->set_line_color(color.r, color.g, color.b);
329 void Turtle::set_line_color(u8 r, u8 g, u8 b)
331 ActionData data;
332 data.next_color[0] = r; data.next_color[1] = g; data.next_color[2] = b;
333 actions.push(Action(Instruction::LineChangeColor, data));
336 void Turtle::set_line_color(u8 color[3])
338 this->set_line_color(color[0], color[1], color[2]);
341 void Turtle::turn_left(float deg)
343 this->turn_right(-deg);
346 void Turtle::turn_right(float deg)
348 // deg += deg < 0 ? 360. : 0.; //! If the angle is negative, we make it positive again
349 deg -= deg >= 360.0 ? 360. : 0.; //! Likewise, we must decrease the angle if it's too big
350 ActionData data; data.rot_angle = deg;
351 actions.push(Action(Instruction::Rotate, data));
354 void Turtle::forward(int32_t units)
356 ActionData data; data.walk_dist = units;
357 actions.push(Action(Instruction::Walk, data));
360 void Turtle::backwards(int32_t units)
362 this->forward(-units);
365 void Turtle::_draw_all_lines(bool clear_screen)
367 if (clear_screen)
369 window.clear(sf::Color::White);
371 for (auto line : lines)
373 sf::Vertex line_vertices[2] = {
374 sf::Vertex(sf::Vector2f(line.xi, line.yi)),
375 sf::Vertex(sf::Vector2f(line.xf, line.yf))
377 line_vertices[0].color = line.color;
378 line_vertices[1].color = line.color;
379 window.draw(line_vertices, 2, sf::Lines);
383 void Turtle::_draw_line(Line new_line)
385 _draw_all_lines();
387 if (m_pen_down)
389 sf::Vertex line_vertices[2] = {
390 sf::Vertex(sf::Vector2f(new_line.xi, new_line.yi)),
391 sf::Vertex(sf::Vector2f(new_line.xf, new_line.yf))
394 line_vertices[0].color = new_line.color;
395 line_vertices[1].color = new_line.color;
397 window.draw(line_vertices, 2, sf::Lines);
401 void Turtle::_draw_sprite()
404 // sprite.setRotation(this->angle);
405 _draw_all_lines();
406 window.draw(sprite);
407 window.display();
411 //! \brief Turtle::_rotate
413 void Turtle::_rotate(float deg)
415 // auto cur_pos = sprite.getLocalBounds();
417 if(verbosity >= Verbosity::Verbose)
419 fprintf(stderr, "Turtle::_rotate(%.2f) started. Current angle: %.2f.\n", deg, this->angle);
422 sprite.setOrigin(16, 16);
423 const float obj = this->angle + deg; //! Final angle to be had
424 if (deg > 0)
426 for (; this->angle < obj; this->angle+=this->rot_vel)
428 sprite.setRotation(this->angle);
429 this->_draw_sprite();
431 } else {
432 for (; this->angle > obj; this->angle-=this->rot_vel)
434 sprite.setRotation(this->angle);
435 this->_draw_sprite();
439 //! The angles need to be in the [0, 360) range
440 this->angle += this->angle < 0 ? 360. : 0.; //! If the angle is negative, we make it positive again
441 this->angle -= this->angle >= 360.0 ? 360. : 0.; //! Likewise, we must decrease the angle if it's too big
443 if(verbosity >= Verbosity::VeryVerbose)
445 fprintf(stderr, "Turtle::_rotate(%.2f) finished. Current angle: %.2f.\n", deg, this->angle);
451 //! \brief Turtle::_walk
453 void Turtle::_walk(int32_t distance)
455 if (verbosity >= Verbosity::Verbose)
457 fprintf(stderr, "Turtle::_walk(%d) started. Current pos: (%d, %d). Current angle: %f\n", distance, this->x, this->y, angle);
460 const float ang_rad = angle*m_deg_to_rad; //! Converts the current angle to radians
462 const sf::Vector2f ep (x + sin(ang_rad) * distance, y - cos(ang_rad) * distance); //! ep := the final point
464 float x_spd = 0., y_spd = 0.f; //! The speed in which the turtle will walk in the x and y direction
465 int x_iters = 0, y_iters = 0; //! How many times we'll update each coordinate
467 if (x > ep.x)
469 x_spd = -walk_spd; //! Our end-point has a smaller x-coord, so we have to decrease it.
470 } else if (x < ep.x) {
471 x_spd = walk_spd; //! Our end-point has a greater x-coord, so we have to decrease it.
472 } //! if x == ep.x, the default of 0.0f will keep them equal
474 x_iters = std::abs((x - ep.x)/walk_spd); //! Approximately how many times we'll have to update the x-coord.
476 if (y > ep.y) //! The same logic applies to the y-coordinate
478 y_spd = -walk_spd;
479 } else if (y < ep.y)
481 y_spd = walk_spd;
484 y_iters = std::abs((y - ep.y)/walk_spd);
486 Line line(x, y, this->line_color);
488 //! TODO: use the same formula used on `ep` to calculate middle-steps
489 while((x_iters >= 0) || (y_iters >= 0))
491 if (x_iters-- >= 0) { x += x_spd; }
492 if (y_iters-- >= 0) { y += y_spd; }
493 line.xf = x; line.yf = y;
494 sprite.setPosition(x, y);
495 _draw_line(line);
496 window.draw(sprite);
497 window.display();
499 sprite.setPosition(ep); //! The loop above only gets us close to the correct end-point, so we'll get there correctly now
500 line.xf = ep.x;
501 line.yf = ep.y;
502 _draw_sprite();
504 if (m_pen_down) {
505 //! We only need to save this line if the pen was down
506 lines.push_back(line);
509 if(verbosity >= Verbosity::VeryVerbose){
510 fprintf(stderr, "Turtle::_walk(%d) finished. Current pos: (%d, %d).\n", distance, this->x, this->y);
515 //! \brief Turtle::init initializes Turtle variables
517 void Turtle::init()
519 this->verbosity = Verbosity::Quiet;
520 this->x = width/2;
521 this->y = height/2;
522 this->rot_vel = 0.5;
523 this->m_pen_down = true;
524 this->walk_spd = 1;
525 this->angle = 0;
526 this->line_color = sf::Color::Black;
530 //! \brief Turtle::_idle keeps rendering a static scene
532 void Turtle::_idle()
534 //! TODO: check for window events here
535 for (;;) { _draw_all_lines(); window.draw(sprite); window.display(); }
538 void Turtle::set_window_title(const std::string& new_title)
540 this->window.setTitle(new_title);
543 void Turtle::set_icon(sf::Texture t)
545 //! TODO: check lifetime
546 texture = t;
547 sprite.setTexture(t);
550 void Turtle::set_icon(Icon icon)
552 if (icon == Icon::Arrow)
554 //! TODO
555 } else {
556 texture.loadFromMemory(__turtle_png, 1479);
559 sprite.setTexture(texture);
564 //! \brief Turtle::act runs through the action queue and animates the turtle
566 void Turtle::act()
568 if (title.empty())
570 title = "Ruga Window";
572 if (sprite.getTexture() == nullptr)
574 //! Icon not set, default to turtle.
575 set_icon(Icon::Turtle);
578 fprintf(stderr, "\nStarting act() with actions.size() = %ld\n", actions.size());
580 window.create(sf::VideoMode(width, height), title);
582 while (window.isOpen())
584 sf::Event event;
585 while (window.pollEvent(event))
587 if (event.type == sf::Event::Closed) { window.close(); }
589 // sprite.setPosition(x, y);
591 //! _idle until user closes the window
592 if(actions.empty()) { _idle(); } //! TODO: check events within _idle
594 Action current = actions.front(); actions.pop();
596 switch (current.instr)
598 case Instruction::Rotate:
599 _rotate(current.data.rot_angle);
600 break;
601 case Instruction::Walk:
602 _walk(current.data.walk_dist);
603 break;
604 case Instruction::PenMovement:
605 m_pen_down = current.data.pen_down;
606 break;
607 case Instruction::Screenshot:
608 _save_to_image(current.data.filename);
609 break;
610 case Instruction::LineChangeColor:
611 const auto newc = current.data.next_color;
612 this->line_color = sf::Color(newc[0], newc[1], newc[2]);
613 break;
614 // case Instruction::SpriteChangeColor:
615 // break;
620 #endif