Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » I need help with my text drawing function

This thread is locked; no one can reply to it. rss feed Print
I need help with my text drawing function
ISDcaptain
Member #15,087
May 2013

Okay Im making a Zelda clone, and Im trying to implement that iconic Zelda text box style. You know where it makes a small beep with each letter?
Any ways here is my code

#SelectExpand
1 2//Draw text function 3void drawText(char text[], int x, int y) 4{ 5 //Get the size of the text 6 int n = strlen(text); 7 8 //Should the program draw the text on screen? 9 if(drawingtext) 10 { 11 //Now draw each letter in the char array 12 for(int i = 0; i < n; i++) 13 { 14 //Draw the letter 15 al_draw_text(font, al_map_rgb(255, 255, 255), x, y, NULL, text); 16 17 //Play the beep 18 al_play_sample_instance(beepInstance); 19 20 //Rest the program 21 al_rest(10); 22 } 23 } 24 else 25 return; 26}

My problem is in the function al_draw_text(), how do I draw each piece of char array at a time, rather than all of it? I want use text[i] as my parameter instead of just text. What should I do?

DanielH
Member #934
January 2001
avatar

#SelectExpand
1 //Draw text function 2 void drawText(char text[], int x, int y) 3 { 4 //Get the size of the text 5 int n = strlen(text); 6 7 //Should the program draw the text on screen? 8 if(drawingtext) 9 { 10 char s[2]={0,0}; 11 int px = x; 12 13 //Now draw each letter in the char array 14 for(int i = 0; i < n; i++) 15 { 16 //Draw the letter 17 //al_draw_text(font, al_map_rgb(255, 255, 255), x, y, NULL, text); 18 s[0]=text[i]; 19 20 al_draw_text(font, al_map_rgb(255, 255, 255), px, y, NULL, s); 21 22 px += al_get_text_width(font,s); 23 24 //Play the beep 25 al_play_sample_instance(beepInstance); 26 27 //Rest the program 28 al_rest(10); 29 } 30 } 31 else 32 return; 33}

SiegeLord
Member #7,827
October 2006
avatar

I'm not sure that will respect glyph kerning... I'd personally use ALLEGRO_USTR for this:

ALLEGRO_USTR_INFO info;

const ALLEGRO_USTR* ustr = al_ref_buffer(&info, text, (size_t)i);
al_draw_ustr(font, al_map_rgb(255, 255, 255), x, y, 0, ustr);

Note that that will redraw the initial letters every time, so you need to clear the textbox every frame. I certainly would not use al_rest like that. Instead, I would increment i every 10 ticks or something (and not use a loop). Or, alternatively, I'd pass the start tick and the current tick to the drawText function and have it figure out the value of i from that.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

ISDcaptain
Member #15,087
May 2013

Yeah im running into problems. The beep keeps on going on, and it doesn't draw each letter one at a time, I don't know what to do.

Kris Asick
Member #1,424
July 2001

al_draw_textf(font, al_map_rgb(255, 255, 255), x, y, NULL, "%c", text[i]);

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Edgar Reynaldo
Member #8,592
May 2007
avatar

Kris - see what SiegeLord said about kerning.

Yeah im running into problems. The beep keeps on going on, and it doesn't draw each letter one at a time, I don't know what to do.

Create a timer that beats as often as you want your letters to appear. Each time you get a timer event you increment a counter like n. Then when you draw, you draw n out of the total number of letters where n is the number of timer ticks passed since you started it. Each time you get a timer event play the sound. That should solve your problems.

Draw it like SiegeLord suggested, with al_ref_buffer or al_ref_ustr.

Kris Asick
Member #1,424
July 2001

Kris - see what SiegeLord said about kerning.

*nods* Yeah, for variable width fonts, simply looping through all the characters isn't going to work very nicely without some extra code, though I thought I'd inject that little bit of code into the conversation as a quick "make it work right now" approach. Refinements can come afterwards. ;)

--- Kris Asick (Gemini)
--- http://www.pixelships.com

ISDcaptain
Member #15,087
May 2013

Okay how would I go about doing that with a timer? I don't know much about them other than how to use them to regulate the FPS.

Edgar Reynaldo
Member #8,592
May 2007
avatar

ISDcaptain
Member #15,087
May 2013

K I created a timer:

ALLEGRO_TIMER *textTimer = NULL

How do I get it to tick with each letter:

textTimer = al_create_timer(?/?); ??

I don't know what to do here.

Edgar Reynaldo
Member #8,592
May 2007
avatar

al_create_timer

ALLEGRO_TIMER* al_create_timer(double speed_secs)

Introduced in 5.0.0

Install a new timer. If successful, a pointer to a new timer object is returned, otherwise NULL is returned. speed_secs is in seconds per "tick", and must be positive. The new timer is initially stopped.

The system driver must be installed before this function can be called.

Usage note: typical granularity is on the order of microseconds, but with some drivers might only be milliseconds.

See also: al_start_timer, al_destroy_timer

Waiting on an event queue for a timer event :

#SelectExpand
1int letterCount = 0; 2ALLEGRO_TIMER* textTimer = al_create_timer(seconds_per_letter); 3ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue(); 4 5if (!textTimer || !queue) {Fail();} 6 7al_register_event_source(queue , al_get_timer_event_source(textTimer)); 8 9// When you start writing your text : 10letterCount = 0; 11al_start_timer(textTimer); 12 13// In your program loop 14do { 15 16 ALLEGRO_EVENT ev; 17 al_wait_for_event(queue , &ev); 18 19 if (ev.type == ALLEGRO_EVENT_TIMER) { 20 ++letterCount; 21 PlayBeep(); 22 redraw = true; 23 } 24} while(!al_is_event_queue_empty()); 25 26if (redraw) { 27 // draw your text here 28}

Go to: