![]() |
|
why is my code failing |
J43G3R
Member #20,281
June 2021
|
I have the following code for displaying respawning message for my character.It basically displays the strings : Respawing in ... 3,Respawing in ... 2,Respawing in ... 1 with 1 sec interval in between. Here's the code 1void respawn_wait(){
2 int wait_timer=0;
3 int time_remaining=3;
4 char string[20];
5 ALLEGRO_FONT* local_font = al_create_builtin_font();
6 if(!local_font){
7 printf("local_font variable can't be initialized\n");
8 exit(1);
9 }
10 ALLEGRO_TRANSFORM local_trans;
11 al_identity_transform(&local_trans);
12 al_translate_transform(&local_trans,SC_WIDTH/2,SC_HEIGHT/2);
13 al_use_transform(&local_trans);
14 while(time_remaining!=0){
15 al_wait_for_event(game->queue,&(game->event));
16 if(game->event.type==ALLEGRO_EVENT_TIMER){
17 wait_timer++;
18 }
19 if(wait_timer==30){
20 sprintf(string,"Respawning in ... %d",time_remaining);
21 time_remaining--;
22
23 al_draw_text(local_font,al_map_rgb(255,255,255),0,0,0,string);
24 wait_timer=0;
25 }
26 }
27}
but it fails with this error message: /build/allegro5-F6iykb/allegro5-5.2.6.0/src/transformations.c:32: al_copy_transform: Assertion `src' failed. why so ...? |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
I don't see anything wrong with the code in the function you posted. Have you changed the projection transform at all? It's complaining about a null src transform, and from the code you showed me I don't see where it would be null. EDIT My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
J43G3R
Member #20,281
June 2021
|
All right, solved!!! I extended its scope as you said and It worked as expected. Thankyou😄 |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Congrats. Also, don't forget to destroy fonts when you are done with them. Happy coding! My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
J43G3R
Member #20,281
June 2021
|
The code worked fine for a few "respawns" but after that I noticed that a bug has found its way in the code for the function respawn_wait() which I modified a little as the previous was a little off( the al_draw_text was meant to be in the "if(event=timer)" code block. Anyways the bug that has arisen causes my game to freeze completely when the character dies,and this one is very hard to trace as it does not happen everytime... and I know this is caused by respawn_wait() as without it, the game works just fine. Here's respawn_wait() v2.0: 1void respawn_wait(){
2 int wait_timer=0;
3 int time_remaining=3;
4 char string[20];
5 local_font= al_create_builtin_font();
6 if(!local_font){
7 printf("local_font variable can't be initialized\n");
8 exit(1);
9 }
10 al_identity_transform(&local_trans);
11 al_scale_transform(&local_trans,2,2);
12 al_translate_transform(&local_trans,SC_WIDTH/2,SC_HEIGHT/2);
13 al_use_transform(&local_trans);
14 al_flush_event_queue(game->queue);
15 sprintf(string,"Respawning in ... %d",time_remaining);
16 while(1){
17
18
19 al_wait_for_event(game->queue,&(game->event));
20 if(game->event.type==ALLEGRO_EVENT_TIMER){
21 wait_timer++;
22 al_clear_to_color(al_map_rgb(0,0,0));
23 al_draw_text(local_font,al_map_rgb(255,255,255),0,0,ALLEGRO_ALIGN_CENTRE,string);
24 al_flip_display();
25
26 }
27 if(wait_timer==30){
28 time_remaining--;
29 wait_timer=0;
30 sprintf(string,"Respawning in ... %d",time_remaining);
31 }
32 if(time_remaining == 0){
33 al_destroy_font(local_font);
34 break;
35
36 }
37 }
38 game->state &= ~(RESPAWNING);
39
40}
I'm asking here as I thought this might be an issue relating to ALLEGRO EVENTS and I'm struggling to understand the documentation,and to be frank the documentation is not that good for beginners. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Do you mind showing more code? Timer events may be piling up in the exit of the function, causing a lag in main and the subsequent freeze of the game. Just show me the main loop. You could try pausing the timer until you return, or clearing the event queue. Are you using the official docs on liballeg.org? What do you feel is lacking? We can always edit them to be more clear based on your feedback. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
J43G3R
Member #20,281
June 2021
|
Ok here's the main loop, there are very little comments on how everything works, but not that hard to understand, since I am a beginner 1void play_game(){
2 pthread_t blast_handler;
3 pthread_t collider_thread;
4 pthread_t create_asteroids;
5 int blink_timer=0;
6 if(pthread_create(&collider_thread,NULL,collider,NULL)){
7 printf("FATAL : Could not create collider thread : %s",strerror(errno));
8 exit(1);
9 }
10
11 if(pthread_create(&blast_handler,NULL,handle_blast,NULL))
12 { printf("FATAL : Could not create blast handling thread : %s",strerror(errno));
13 exit(1);
14 }
15
16 if(pthread_create(&create_asteroids,NULL,generate_new_asteroids,NULL))
17 { printf("FATAL : Could not create asteroid generating thread: %s",strerror(errno));
18 exit(1);
19}
20
21 ALLEGRO_COLOR acolor=al_map_rgb(0,255,0);
22 bool left=false,right=false,up=false,down=false,space=false,shift=false,redraw=false,escape=false;
23 while(1){
24 if(!(game->state & RESPAWNING))
25 al_wait_for_event(game->queue,&game->event);
26 if(game->event.type==ALLEGRO_EVENT_TIMER){
27
28 redraw=true; // makes sure that only the timer event triggers the display to advance
29
30 pthread_mutex_lock(&blast_lock_handle_blast); // prevents stepping on the toe of handle blast thread
31
32 if(game->blasts_on_screen)
33 clean_blasts(); //cleans dead blasts if any
34
35 pthread_mutex_unlock(&blast_lock_handle_blast);
36
37 handle_collision(); // handles collision b/w asteroids
38
39 pthread_mutex_lock(&ast_lock);
40
41 clean_asteroids(); //cleans dead asteroids
42
43 pthread_mutex_unlock(&ast_lock);
44
45 blink_timer++;
46
47 //generate_new_asteroids();
48 }
49 if(game->event.type==ALLEGRO_EVENT_KEY_DOWN){
50 switch(game->event.keyboard.keycode){
51 case(ALLEGRO_KEY_D):
52 right=true;
53 break;
54 case(ALLEGRO_KEY_A):
55 left=true;
56 break;
57 case(ALLEGRO_KEY_W):
58 up=true;
59 break;
60 case(ALLEGRO_KEY_S):
61 down=true;
62 break;
63 case(ALLEGRO_KEY_SPACE):
64 space=true;
65 break;
66 case(ALLEGRO_KEY_LSHIFT):
67 shift=true;
68 break;
69
70 case(ALLEGRO_KEY_ESCAPE):
71 escape=true;
72 break;
73 }
74
75 }
76 if(game->event.type==ALLEGRO_EVENT_KEY_UP){
77 switch(game->event.keyboard.keycode){
78 case(ALLEGRO_KEY_D):
79 right=false;
80 break;
81 case(ALLEGRO_KEY_A):
82 left=false;
83 break;
84 case(ALLEGRO_KEY_W):
85 up=false;
86 break;
87 case(ALLEGRO_KEY_S):
88 down=false;
89 break;
90 case(ALLEGRO_KEY_LSHIFT):
91 shift=false;
92 break;
93
94 }
95 }
96
97 if(!up ){
98 speed=0;
99 }
100 if(up)
101 {
102 speed=4;
103 if(shift){
104 if(speed<MAX_SPEED)
105 speed+=ACC;
106 }
107 }
108 if(left)
109 {
110 if((theta_in_radians -= OMEGA)<0)
111 theta_in_radians = 6.2832+theta_in_radians;
112
113 rotate_object(trans,x,y,-OMEGA); // gracefully rotates the spaceship
114 }
115 if(right)
116 {
117 if((theta_in_radians += OMEGA)>6.2832)
118 theta_in_radians-=6.2832;
119 rotate_object(trans,x,y,OMEGA);
120 }
121 if(space)
122 {
123 pthread_mutex_lock(&blast_lock_handle_blast);
124 generate_blast(x,y,theta_in_radians); // fire that blast!!!
125 pthread_mutex_unlock(&blast_lock_handle_blast);
126 game->blasts_on_screen++;
127 space=false;
128 }
129 if(escape){
130 //change the state of the game
131
132 game->state |= GAME_STARTED;
133 game->state |= GAME_PAUSED;
134 break;
135 }
136
137 if(game->event.type==ALLEGRO_EVENT_DISPLAY_CLOSE)
138 exit(1);
139 // save_and_exit(); not yet implemented !
140
141 if(redraw && al_is_event_queue_empty(game->queue)) {
142
143 al_clear_to_color(al_map_rgb(0,0,0));
144 draw_each_asteroid(); // advance the asteroids one frame and draw each of them
145
146 if(!(game->state & RESPAWNING)) // we do not want the spaceship to be still visible on the screen after as-sp collision
147
148 {
149 if(speed){
150 x= translate_spaceship_x(trans,speed,SC_WIDTH,theta_in_radians,x); // if(speed), move the spaceship in the x co-ordinate
151 y=translate_spaceship_y(trans,speed,SC_HEIGHT,theta_in_radians,y);// if(speed), move the spaceship in the y co-ordinate
152 }
153 al_use_transform(trans);
154
155 if((game->state & PROT_SP) && (blink_timer==5)) {
156 al_draw_circle(0,0,20,al_map_rgb(255,255,255),3.0f);
157 blink_timer=0; // causes the respawn shield/circle, which indicates that the spaceship can't be harmed, to blink...
158 }
159 else if(blink_timer > 5) blink_timer%=5;
160
161 {
162 al_draw_line(SCALE*(0.5),SCALE*(0.28867),0,SCALE*(-0.577),acolor,3.0f);
163 al_draw_line(SCALE*(-0.333),0,SCALE*(-0.1),0,acolor,3.0f);
164 al_draw_line(SCALE*(0.333),0,SCALE*(0.1),0,acolor,3.0f);
165 al_draw_line(SCALE*(-0.5),SCALE*(0.28867),0,SCALE*(-0.577),acolor,3.0f);
166 } // draw the spaceship
167
168
169 if(game->blasts_on_screen)
170 draw_each_blast();
171 }
172 else{
173 respawn_wait();
174 left=false,right=false,up=false,down=false,space=false,shift=false,escape=false;
175 }
176 }
177
178 al_flip_display();
179 redraw=false;
180
181 }
182 }
183}
PS : About the game...its actually a really amateur clone of the legendary arcade game "blasteroids" |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Ok. Here goes. Since you're still a beginner, I recommend serial programming instead of parallel programming, but since you're already in the deep end, I'll take a guess and say that you're stuck in a classic deadlocked thread scenario. Without seeing the functions run by your threads, I can only guess at what is wrong. You have 4 threads (or more) running in parallel counting main. If you're not careful, you'll end up locking one thread that depends on another that is already locked that depends on the first. This is a deadlock. Deadlocks are also known as The Dining Philosopher's problem. You can read more about it on wikipedia. Are you familiar with debugging tools? When your game freezes, break execution and see which threads are where. You should easily be able to see which thread is waiting on which. Other than that, try serial programming or show the other functions that are running concurrently to main. Blasteroids is a relatively simple program and can easily be done without the use of threads. Hope this helps, My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
J43G3R
Member #20,281
June 2021
|
I knew what a deadlock was, I am not that much of a beginner, but I didn't see one in my threads, maybe I glossed over something, so here are all the thread functions: first one ( handle_blast(), checks whether any of the blast hit any of the asteroids) 1void* handle_blast(void* null){
2 while(1){
3 if(!(game->state & RESPAWNING)){
4 pthread_mutex_lock(&blast_lock_handle_blast);
5 blast* bl_ptr=game->bl_null;
6 for(int i=0;i<game->blasts_on_screen;i++){
7 asteroid* as_ptr=game->as_null;
8 if(bl_ptr->next && bl_ptr->next->alive){
9 bl_ptr=bl_ptr->next;
10 pthread_mutex_lock(&ast_lock);
11 int itr=game->asteroids_on_screen;
12 for(int y=0;(y<itr);y++){
13 as_ptr=as_ptr->next;
14 if(!as_ptr->alive) continue;
15 if(calc_distance(as_ptr->x,as_ptr->y,bl_ptr->x,bl_ptr->y)<23){
16 if(as_ptr->scale == 1) break_asteroid(as_ptr,bl_ptr);
17 bl_ptr->alive=false;
18 as_ptr->alive=false;
19 break;
20 }
21 }
22 pthread_mutex_unlock(&ast_lock);
23 }
24 }
25 pthread_mutex_unlock(&blast_lock_handle_blast);
26 }
27}
28
29}
..second one (collider() handles collision b/w spaceship and asteroids) 1void *collider(void *null){
2
3 static int sleep_count=0;
4 static int i=0;
5 while(1){
6 if(!((game->state & RESPAWNING))){
7 if((game->state & PROT_SP) || (game->state & NEW_GAME_STARTED) || (game->state & SP_RESPAWN)){
8 if(game->state & NEW_GAME_STARTED){
9 game->state &= ~(NEW_GAME_STARTED);
10 game->state |= PROT_SP;
11 sleep_count=0;
12 i=0;
13 }
14 if(game->state & SP_RESPAWN){
15 game->state &= ~(SP_RESPAWN);
16 game->state |= PROT_SP;
17 sleep_count=0;
18 i=0;
19 }
20 for(;i<3;i++){
21 sleep(1);
22 sleep_count++;
23 }
24 game->state &= ~PROT_SP;
25 sleep_count=0;
26 i=0;
27 }
28
29 if(game->event.type==ALLEGRO_EVENT_TIMER){
30 pthread_mutex_lock(&ast_lock);
31 handle_sp_collision(&x,&y,&theta_in_radians);
32 pthread_mutex_unlock(&ast_lock);
33 }
34 }
35
36 }
37}
... and the last(generate_new_asteroids(), generates new asteroids when the count falls below 3 ) 1
2void* generate_new_asteroids(void *null){
3 while(1){
4 int itr=game->asteroids_on_screen;
5 if(itr <= 2){
6 srand(time(0));
7 asteroid* ptr;
8 for(int i=0;i < 5; i++){
9 ptr= (asteroid* )(malloc(sizeof(asteroid)));
10 int X=rand()%2;
11 int Y=rand()%2;
12 int is_negative_X = 1;
13 int is_negative_Y = 1;
14 for(int i=0;i<=X;i++){
15 is_negative_X*=-1;
16 }
17 for(int i=0;i<=Y;i++){
18 is_negative_Y*=-1;
19 }
20 ptr->speed_x = ((float)(rand())/(float)(RAND_MAX))*SPEED_X*is_negative_X;
21 ptr->speed_y=((float)(rand())/(float)(RAND_MAX))*SPEED_Y*is_negative_Y;
22 X=rand()%4;
23 switch(X){
24 case 0:
25 ptr->x = (float)(rand()%SC_WIDTH);
26 ptr->y = -23;
27 break;
28 case 1:
29 ptr->x = (float)(rand()%SC_WIDTH);
30 ptr->y = SC_HEIGHT+23;
31 break;
32 case 2:
33 ptr->x = -23;
34 ptr->y= (float)(rand()%SC_HEIGHT);
35 break;
36 case 3:
37 ptr->x = SC_WIDTH + 23;
38 ptr->y = (float)(rand()%SC_HEIGHT);
39 break;
40 }
41 ptr->scale=1;
42 ptr->alive=true;
43 ptr->current_rotation=(rand()%20)*0.01+0.05;
44 ptr->omega=ptr->current_rotation+0.05;
45 ptr->color = al_map_rgb(255,255,255);
46 ptr->trans = (ALLEGRO_TRANSFORM*)(malloc(sizeof(ALLEGRO_TRANSFORM)));
47 al_identity_transform((ptr->trans));
48
49 ptr->next=game->as_null->next;
50 game->as_null->next=ptr;
51 game->asteroids_on_screen++;
52
53 }
54 }
55}
56}
I am using threads to speed up my game as I am not using sprite animation, but actual math and physics for animating the asteroids and collision b/w them which is computationally intensive and thus to make my game playable(fast enough), I divided the work among threads. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
To be honest, you could have 100s of asteroids and 100s of blasts and still not need threads. All they do is complicate things, and most the time they are unnecessary. That said, your handle_blast function has a mismatched lock / unlock. They are in different braces. So lock is only called when not respawning, but unlock is always called. This is probably UB. Second, your generate new asteroids function is not protected by a mutex. This can lead to a race condition in your asteroid list. Another thing, you can only draw to the display that is current for the calling thread. This means your respawn wait function is drawing to a display that is not current. Honestly, you're making this much harder than it needs to be. The A5teroids demo included with allegro is probably not threaded. You could look to it for inspiration if you like. It's called cosmic protector. Other than that, the threading seems clean, but there is a potential for deadlocks when modifying asteroids since more than one thread changes the asteroid list. General things to think about when threading : Make your critical sections as small and as fast as possible. Avoid race conditions by specifying which data each thread will modify. Again, a debugger would probably solve this quickly. Happy hunting. Edgar My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
J43G3R
Member #20,281
June 2021
|
I don't think that if I had 100 asteroids and 100 blasts on screen, my game would remain playable without threads, as currently, even with the use of threads and just 8 asteroids on the screen , my game sucks😅(lags terribly). Also please look again carefully at the handle blast function, the mutex unlock falls within the brace of if(! Respawn) condition. Further, if you take a look at the generate new asteroids function, you will see that I have deferred actually changing the as_null list till the last second line of the function, and all the threads that read the list of asteroids will not be affected by any other thread that just increases the number of asteroids as they will(for only a short amount of time till the number of asteroids on screen variable is incremented) just read the shorter version of list and that will not cause SIGSEGV fault as the memory being accessed is completely reliable..... and as for the debugging tools I don't know how to debug deadlocks using GDB😅 but if you can suggest some better debugger then I would really appreciate it😊 [SOLVED!!!] The bug was in this condition in the main loop coupled by the racing collider thread that set the game state to respawning but if it set respawning before the if(!respawning) condition then the respawn_wait function will never be called as it is enclosed by a condition block in which one of the condition is that the redraw variable be set to true 1 if(redraw && al_is_event_queue_empty(game->queue)) {
2
3 al_clear_to_color(al_map_rgb(0,0,0));
4 draw_each_asteroid(); // advance the asteroids one frame and draw each of them
5
6 if(!(game->state & RESPAWNING)) // we do not want the spaceship to be still visible on the screen after as-sp collision
7
8 {
9 if(speed){
10 x= translate_spaceship_x(trans,speed,SC_WIDTH,theta_in_radians,x); // if(speed), move the speed in the x co-ordinate
11 y=translate_spaceship_y(trans,speed,SC_HEIGHT,theta_in_radians,y);// if(speed), move the speed in the y co-ordinate
12 }
13 al_use_transform(trans);
14
15 if((game->state & PROT_SP) && (blink_timer==5)) {
16 al_draw_circle(0,0,20,al_map_rgb(255,255,255),3.0f);
17 blink_timer=0; // causes the respawn shield/circle, which indicates that the spaceship can't be harmed, to blink...
18 }
19 else if(blink_timer > 5) blink_timer%=5;
20
21 {
22 al_draw_line(SCALE*(0.5),SCALE*(0.28867),0,SCALE*(-0.577),acolor,3.0f);
23 al_draw_line(SCALE*(-0.333),0,SCALE*(-0.1),0,acolor,3.0f);
24 al_draw_line(SCALE*(0.333),0,SCALE*(0.1),0,acolor,3.0f);
25 al_draw_line(SCALE*(-0.5),SCALE*(0.28867),0,SCALE*(-0.577),acolor,3.0f);
26 } // draw the spacehip
27
28
29 if(game->blasts_on_screen)
30 draw_each_blast();
31 }
32 else{
33 respawn_wait();
34 left=false,right=false,up=false,down=false,space=false,shift=false,escape=false;
35 }
36
37 al_flip_display();
38 redraw=false;
39
40 }
41 }
42}
.. ....which is only done by the if(event=timer) condition block 1 if(game->event.type==ALLEGRO_EVENT_TIMER){
2
3 redraw=true; // makes sure that only the timer event triggers the display to advance
4
5 pthread_mutex_lock(&blast_lock); // prevents stepping on the toe of handle blast thread
6
7 if(game->blasts_on_screen)
8 clean_blasts(); //cleans dead blasts if any
9
10 pthread_mutex_unlock(&blast_lock);
11
12 handle_collision(); // handles collision b/w asteroids
13
14 pthread_mutex_lock(&ast_lock_handle_blast);
15 pthread_mutex_lock(&ast_lock_collider);
16
17 clean_asteroids(); //cleans dead asteroids
18
19 pthread_mutex_unlock(&ast_lock_handle_blast);
20 pthread_mutex_unlock(&ast_lock_collider);
21
22 blink_timer++;
23}
and that block will never get executed if we don't wait for event and thus the game is stuck in a while(1) like state thus frozen forever. Man now I see how peculiar deadlock bugs can get:o:o |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
I misread handle_blast. You are correct. The poor indentation makes it hard to read properly. What kind of collision checks are you doing? Circle overlap? Pixel perfect? A 2 GHZ processor could handle millions of checks per second and not be stressed. What is your target platform? About GDB, when your program freezes, hit CTRL-C inside GDB and then do : thread apply all bt It will show you a backtrace for every thread in existence. One thread is bound to be stuck on pthread_mutex_lock, and if deadlocked another thread will be inside a different mutex lock. Would you mind packaging a zip of your sources and resources for me? I can debug it much more effectively that way. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
J43G3R
Member #20,281
June 2021
|
No need, I am saying that I solved the bug, please read the [SOLVED] part that I have added later, and regarding collision checks... to check between two asteroids I am using circle overlap, because the shape of asteroids is mostly circular and for the collision between spaceship(which is essentially triangular) and asteroid, I am performing a completely different chicanery, involving use of Pythagoras theorem and distance between a point and a line, that is something only I can read and understand😅😅, but it is working like a treat!!! And the platform on which I am currently running the game is an Ubuntu guest OS(alloc 6gb ram and both the cores) running on Windows (Intel i3 6100U 12 gb ram, 2.3GHz clock speed dual core) as host and VirtualBox manager. Although in future I would like to port it to different OS and architectures |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Well, I'm glad you solved it. Hopefully I was of some help. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
J43G3R
Member #20,281
June 2021
|
Yeah you were a great guiding hand for a beginner like me. Thanks a lot😄, without your help, I would have felt so lost😅 |
Arthur Kalliokoski
Second in Command
February 2005
![]() |
J43G3R said: Thanks a lot😄, without your help, I would have felt so lost😅 Search his comment history, he's been doing this for years. They all watch too much MSNBC... they get ideas. |
J43G3R
Member #20,281
June 2021
|
Yeah, a real life saver👏👏👍👍 |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Didn't you guys know, my only porpoise in life is to help teh newbs. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
DanielH
Member #934
January 2001
![]() |
{"name":"613024","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/f\/ff2ef87e297798db70f09f8d3e782a4f.png","w":457,"h":429,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/f\/f\/ff2ef87e297798db70f09f8d3e782a4f"} |
|