1616*
1717********************************************************************************************/
1818
19+ #include "raylib.h"
20+
1921#include <stdlib.h>
2022#include <string.h>
2123#include <math.h>
22- #include "raylib.h"
2324
24- #define STR_MAX_SIZE 10000
25- #define TURTLE_STACK_MAX_SIZE 50
25+ #define STR_MAX_SIZE 10000
26+ #define TURTLE_STACK_MAX_SIZE 50
2627
28+ //----------------------------------------------------------------------------------
29+ // Types and Structures Definition
30+ //----------------------------------------------------------------------------------
2731typedef struct TurtleState {
2832 Vector2 origin ;
2933 double angle ;
@@ -40,32 +44,111 @@ typedef struct PenroseLSystem {
4044 float theta ;
4145} PenroseLSystem ;
4246
47+ //----------------------------------------------------------------------------------
48+ // Global Variables Definition
49+ //----------------------------------------------------------------------------------
4350static TurtleState turtleStack [TURTLE_STACK_MAX_SIZE ];
4451static int turtleTop = -1 ;
4552
46- void PushTurtleState (TurtleState state )
53+ //----------------------------------------------------------------------------------
54+ // Module Functions Declaration
55+ //----------------------------------------------------------------------------------
56+ static void PushTurtleState (TurtleState state );
57+ static TurtleState PopTurtleState (void );
58+ static PenroseLSystem CreatePenroseLSystem (float drawLength );
59+ static void BuildProductionStep (PenroseLSystem * ls );
60+ static void BuildPenroseLSystem (PenroseLSystem * ls , float drawLength , int generations );
61+ static void DrawPenroseLSystem (PenroseLSystem * ls );
62+
63+ //------------------------------------------------------------------------------------
64+ // Program main entry point
65+ //------------------------------------------------------------------------------------
66+ int main (void )
4767{
48- if (turtleTop < TURTLE_STACK_MAX_SIZE - 1 )
49- {
50- turtleStack [++ turtleTop ] = state ;
51- }
52- else
68+ // Initialization
69+ //--------------------------------------------------------------------------------------
70+ const int screenWidth = 800 ;
71+ const int screenHeight = 450 ;
72+
73+ SetConfigFlags (FLAG_MSAA_4X_HINT );
74+ InitWindow (screenWidth , screenHeight , "raylib [shapes] example - penrose tile" );
75+
76+ float drawLength = 460.0f ;
77+ int minGenerations = 0 ;
78+ int maxGenerations = 4 ;
79+ int generations = 0 ;
80+
81+ PenroseLSystem ls = {0 };
82+ BuildPenroseLSystem (& ls , drawLength * (generations /(float )maxGenerations ), generations );
83+
84+ SetTargetFPS (60 ); // Set our game to run at 60 frames-per-second
85+ //---------------------------------------------------------------------------------------
86+
87+ // Main game loop
88+ while (!WindowShouldClose ()) // Detect window close button or ESC key
5389 {
54- TraceLog (LOG_WARNING , "TURTLE STACK OVERFLOW!" );
90+ // Update
91+ //----------------------------------------------------------------------------------
92+ bool rebuild = false;
93+ if (IsKeyPressed (KEY_UP ))
94+ {
95+ if (generations < maxGenerations )
96+ {
97+ generations ++ ;
98+ rebuild = true;
99+ }
100+ }
101+ else if (IsKeyPressed (KEY_DOWN ))
102+ {
103+ if (generations > minGenerations )
104+ {
105+ generations -- ;
106+ if (generations > 0 ) rebuild = true;
107+ }
108+ }
109+
110+ if (rebuild ) BuildPenroseLSystem (& ls , drawLength * (generations /(float )maxGenerations ), generations );
111+ //----------------------------------------------------------------------------------
112+
113+ // Draw
114+ //----------------------------------------------------------------------------------
115+ BeginDrawing ();
116+
117+ ClearBackground ( RAYWHITE );
118+
119+ if (generations > 0 ) DrawPenroseLSystem (& ls );
120+
121+ DrawText ("penrose l-system" , 10 , 10 , 20 , DARKGRAY );
122+ DrawText ("press up or down to change generations" , 10 , 30 , 20 , DARKGRAY );
123+ DrawText (TextFormat ("generations: %d" , generations ), 10 , 50 , 20 , DARKGRAY );
124+
125+ EndDrawing ();
126+ //----------------------------------------------------------------------------------
55127 }
128+
129+ // De-Initialization
130+ //--------------------------------------------------------------------------------------
131+ CloseWindow (); // Close window and OpenGL context
132+ //--------------------------------------------------------------------------------------
133+
134+ return 0 ;
135+ }
136+
137+ //----------------------------------------------------------------------------------
138+ // Module Functions Definition
139+ //----------------------------------------------------------------------------------
140+ void PushTurtleState (TurtleState state )
141+ {
142+ if (turtleTop < (TURTLE_STACK_MAX_SIZE - 1 )) turtleStack [++ turtleTop ] = state ;
143+ else TraceLog (LOG_WARNING , "TURTLE STACK OVERFLOW!" );
56144}
57145
58146TurtleState PopTurtleState (void )
59147{
60- if (turtleTop >= 0 )
61- {
62- return turtleStack [turtleTop -- ];
63- }
64- else
65- {
66- TraceLog (LOG_WARNING , "TURTLE STACK UNDERFLOW!" );
67- }
68- return (TurtleState ) {0 };
148+ if (turtleTop >= 0 ) return turtleStack [turtleTop -- ];
149+ else TraceLog (LOG_WARNING , "TURTLE STACK UNDERFLOW!" );
150+
151+ return (TurtleState ){ 0 };
69152}
70153
71154PenroseLSystem CreatePenroseLSystem (float drawLength )
@@ -77,86 +160,19 @@ PenroseLSystem CreatePenroseLSystem(float drawLength)
77160 .ruleY = "-WF++XF[+++YF++ZF]-" ,
78161 .ruleZ = "--YF++++WF[+ZF++++XF]--XF" ,
79162 .drawLength = drawLength ,
80- .theta = 36.0f // in degrees
163+ .theta = 36.0f // Degrees
81164 };
82- ls .production = (char * ) malloc (sizeof (char ) * STR_MAX_SIZE );
165+
166+ ls .production = (char * )RL_MALLOC (sizeof (char )* STR_MAX_SIZE );
83167 ls .production [0 ] = '\0' ;
84168 strncpy (ls .production , "[X]++[X]++[X]++[X]++[X]" , STR_MAX_SIZE );
85- return ls ;
86- }
87-
88- void DrawPenroseLSystem (PenroseLSystem * ls )
89- {
90- Vector2 screenCenter = {GetScreenWidth ()/2 , GetScreenHeight ()/2 };
91-
92- TurtleState turtle = {
93- .origin = {0 },
94- .angle = -90.0f
95- };
96-
97- int repeats = 1 ;
98- int productionLength = (int ) strnlen (ls -> production , STR_MAX_SIZE );
99- ls -> steps += 12 ;
100-
101- if (ls -> steps > productionLength )
102- {
103- ls -> steps = productionLength ;
104- }
105169
106- for (int i = 0 ; i < ls -> steps ; i ++ )
107- {
108- char step = ls -> production [i ];
109- if ( step == 'F' )
110- {
111- for ( int j = 0 ; j < repeats ; j ++ )
112- {
113- Vector2 startPosWorld = turtle .origin ;
114- float radAngle = DEG2RAD * turtle .angle ;
115- turtle .origin .x += ls -> drawLength * cosf (radAngle );
116- turtle .origin .y += ls -> drawLength * sinf (radAngle );
117- Vector2 startPosScreen = {startPosWorld .x + screenCenter .x , startPosWorld .y + screenCenter .y };
118- Vector2 endPosScreen = {turtle .origin .x + screenCenter .x , turtle .origin .y + screenCenter .y };
119- DrawLineEx (startPosScreen , endPosScreen , 2 , Fade (BLACK , 0.2 ));
120- }
121- repeats = 1 ;
122- }
123- else if ( step == '+' )
124- {
125- for ( int j = 0 ; j < repeats ; j ++ )
126- {
127- turtle .angle += ls -> theta ;
128- }
129- repeats = 1 ;
130- }
131- else if ( step == '-' )
132- {
133- for ( int j = 0 ; j < repeats ; j ++ )
134- {
135- turtle .angle += - ls -> theta ;
136- }
137- repeats = 1 ;
138- }
139- else if ( step == '[' )
140- {
141- PushTurtleState (turtle );
142- }
143- else if ( step == ']' )
144- {
145- turtle = PopTurtleState ();
146- }
147- else if ( ( step >= 48 ) && ( step <= 57 ) )
148- {
149- repeats = (int ) step - 48 ;
150- }
151- }
152-
153- turtleTop = -1 ;
154-
170+ return ls ;
155171}
156172
157173void BuildProductionStep (PenroseLSystem * ls )
158174{
159- char * newProduction = (char * ) malloc (sizeof (char ) * STR_MAX_SIZE );
175+ char * newProduction = (char * ) RL_MALLOC (sizeof (char )* STR_MAX_SIZE );
160176 newProduction [0 ] = '\0' ;
161177
162178 int productionLength = strnlen (ls -> production , STR_MAX_SIZE );
@@ -177,97 +193,83 @@ void BuildProductionStep(PenroseLSystem *ls)
177193 {
178194 int t = strnlen (newProduction , STR_MAX_SIZE );
179195 newProduction [t ] = step ;
180- newProduction [t + 1 ] = '\0' ;
196+ newProduction [t + 1 ] = '\0' ;
181197 }
182198 } break ;
183199 }
184200 }
185201
186202 ls -> drawLength *= 0.5f ;
187203 strncpy (ls -> production , newProduction , STR_MAX_SIZE );
188- free ( newProduction );
204+
205+ RL_FREE (newProduction );
189206}
190207
191208void BuildPenroseLSystem (PenroseLSystem * ls , float drawLength , int generations )
192209{
193210 * ls = CreatePenroseLSystem (drawLength );
194- for (int i = 0 ; i < generations ; i ++ )
195- {
196- BuildProductionStep (ls );
197- }
211+ for (int i = 0 ; i < generations ; i ++ ) BuildProductionStep (ls );
198212}
199213
200- //------------------------------------------------------------------------------------
201- // Program main entry point
202- //------------------------------------------------------------------------------------
203- int main (void )
214+ void DrawPenroseLSystem (PenroseLSystem * ls )
204215{
205- // Initialization
206- //--------------------------------------------------------------------------------------
207- const int screenWidth = 800 ;
208- const int screenHeight = 450 ;
209-
210- SetConfigFlags ( FLAG_MSAA_4X_HINT );
211- InitWindow (screenWidth , screenHeight , "raylib [shapes] example - penrose tile" );
212-
213- float drawLength = 460.0f ;
214- int minGenerations = 0 ;
215- int maxGenerations = 4 ;
216- int generations = 0 ;
216+ Vector2 screenCenter = { GetScreenWidth ()/2 , GetScreenHeight ()/2 };
217217
218- PenroseLSystem ls = {0 };
219- BuildPenroseLSystem (& ls , drawLength * (generations / (float ) maxGenerations ), generations );
220-
221- SetTargetFPS (60 ); // Set our game to run at 60 frames-per-second
222- //---------------------------------------------------------------------------------------
218+ TurtleState turtle = {
219+ .origin = {0 },
220+ .angle = -90.0f
221+ };
223222
224- // Main game loop
225- while (!WindowShouldClose ()) // Detect window close button or ESC key
223+ int repeats = 1 ;
224+ int productionLength = (int )strnlen (ls -> production , STR_MAX_SIZE );
225+ ls -> steps += 12 ;
226+
227+ if (ls -> steps > productionLength ) ls -> steps = productionLength ;
228+
229+ for (int i = 0 ; i < ls -> steps ; i ++ )
226230 {
227- // Update
228- //----------------------------------------------------------------------------------
229- bool rebuild = false;
230- if (IsKeyPressed (KEY_UP ))
231+ char step = ls -> production [i ];
232+ if (step == 'F' )
231233 {
232- if ( generations < maxGenerations )
234+ for ( int j = 0 ; j < repeats ; j ++ )
233235 {
234- generations ++ ;
235- rebuild = true;
236+ Vector2 startPosWorld = turtle .origin ;
237+ float radAngle = DEG2RAD * turtle .angle ;
238+ turtle .origin .x += ls -> drawLength * cosf (radAngle );
239+ turtle .origin .y += ls -> drawLength * sinf (radAngle );
240+ Vector2 startPosScreen = { startPosWorld .x + screenCenter .x , startPosWorld .y + screenCenter .y };
241+ Vector2 endPosScreen = { turtle .origin .x + screenCenter .x , turtle .origin .y + screenCenter .y };
242+
243+ DrawLineEx (startPosScreen , endPosScreen , 2 , Fade (BLACK , 0.2 ));
236244 }
237- }
238- else if (IsKeyPressed (KEY_DOWN ))
245+
246+ repeats = 1 ;
247+ }
248+ else if (step == '+' )
239249 {
240- if (generations > minGenerations )
241- {
242- generations -- ;
243- rebuild = generations > 0 ;
244- }
245- }
246- if (rebuild )
250+ for (int j = 0 ; j < repeats ; j ++ ) turtle .angle += ls -> theta ;
251+
252+ repeats = 1 ;
253+ }
254+ else if (step == '-' )
247255 {
248- BuildPenroseLSystem (& ls , drawLength * (generations / (float ) maxGenerations ), generations );
249- }
250- //----------------------------------------------------------------------------------
256+ for (int j = 0 ; j < repeats ; j ++ ) turtle .angle += - ls -> theta ;
251257
252- // Draw
253- //----------------------------------------------------------------------------------
254- BeginDrawing ();
255- ClearBackground ( RAYWHITE );
256- if (generations > 0 )
257- {
258- DrawPenroseLSystem (& ls );
259- }
260- DrawText ("penrose l-system" , 10 , 10 , 20 , DARKGRAY );
261- DrawText ("press up or down to change generations" , 10 , 30 , 20 , DARKGRAY );
262- DrawText (TextFormat ("generations: %d" , generations ), 10 , 50 , 20 , DARKGRAY );
263- EndDrawing ();
264- //----------------------------------------------------------------------------------
258+ repeats = 1 ;
259+ }
260+ else if (step == '[' )
261+ {
262+ PushTurtleState (turtle );
263+ }
264+ else if (step == ']' )
265+ {
266+ turtle = PopTurtleState ();
267+ }
268+ else if ((step >= 48 ) && (step <= 57 ))
269+ {
270+ repeats = (int ) step - 48 ;
271+ }
265272 }
266273
267- // De-Initialization
268- //--------------------------------------------------------------------------------------
269- CloseWindow (); // Close window and OpenGL context
270- //--------------------------------------------------------------------------------------
271-
272- return 0 ;
273- }
274+ turtleTop = -1 ;
275+ }
0 commit comments