|
[a5] keyboard.unichar help needed |
Desmond Taylor
Member #11,943
May 2010
|
I am making input boxes in my game and I am having problems converting the unichar to char. How would I do this. The reason I'm using unichar than keycode is because it's less handling needed for special characters. |
Matthew Leverton
Supreme Loser
January 1999
|
Use a single ALLEGRO_USTR to store multiple unichars (there are plenty of functions for manipulating an ALLEGRO_USTR), and then use the various _ustr drawing functions to output to a bitmap. |
Desmond Taylor
Member #11,943
May 2010
|
Sorry but I really do not get any of that web page :S I use std::string to store my text. It's only converting from unichar to char I need. |
Thomas Fjellstrom
Member #476
June 2000
|
Use an ALLEGRO_USTR instead of a std::string. You get free unicode support that way. -- |
Desmond Taylor
Member #11,943
May 2010
|
I've been trying and I don't get it. I get the unicode number all the time. |
jmasterx
Member #11,410
October 2009
|
1inline size_t encodeUtf8(char outputChars[], int inputUnichar) const
2 {
3 size_t uc = inputUnichar;
4
5 if (uc <= 0x7f) {
6 outputChars[0] = static_cast<char>(uc);
7 return 1;
8 }
9
10 if (uc <= 0x7ff) {
11 outputChars[0] = 0xC0 | ((uc >> 6) & 0x1F);
12 outputChars[1] = 0x80 | (uc & 0x3F);
13 return 2;
14 }
15
16 if (uc <= 0xffff) {
17 outputChars[0] = 0xE0 | ((uc >> 12) & 0x0F);
18 outputChars[1] = 0x80 | ((uc >> 6) & 0x3F);
19 outputChars[2] = 0x80 | (uc & 0x3F);
20 return 3;
21 }
22
23 if (uc <= 0x10ffff) {
24 outputChars[0] = 0xF0 | ((uc >> 18) & 0x07);
25 outputChars[1] = 0x80 | ((uc >> 12) & 0x3F);
26 outputChars[2] = 0x80 | ((uc >> 6) & 0x3F);
27 outputChars[3] = 0x80 | (uc & 0x3F);
28 return 4;
29 }
30
31 /* Otherwise is illegal. */
32 return 0;
33 }
34
35};
This will convert UTF32 (unichar) to UTF-8. 1 inline size_t getUnicharLength(int c) const
2 {
3
4 size_t uc = c;
5
6 if (uc <= 0x7f)
7 return 1;
8 if (uc <= 0x7ff)
9 return 2;
10 if (uc <= 0xffff)
11 return 3;
12 if (uc <= 0x10ffff)
13 return 4;
14 /* The rest are illegal. */
15 return 0;
16}
this will tell you how big your char buffer needs to be for the previous function. Agui GUI API -> https://github.com/jmasterx/Agui |
Desmond Taylor
Member #11,943
May 2010
|
I have it working by doing this: 1 case ALLEGRO_EVENT_KEY_CHAR:
2 {
3 char buf[1];
4 al_utf8_encode( buf, this->event.keyboard.unichar );
5 printf( "%s", buf );
6 }
7 break;
Another noobie question in this simular matter. How do I blank the buffer before using al_utf8_encode? as some special keys mess it up :/ |
jmasterx
Member #11,410
October 2009
|
the (somewhat) proper way: case ALLEGRO_EVENT_KEY_CHAR: { char buf[5]; for(int i = 0; i < 5; ++i) buf[i] = NULL; al_utf8_encode( buf, this->event.keyboard.unichar ); printf( "%s", buf ); } break; Because do not forget, utf-8 != to ascii, it has ascii + tons more so it needs up to 4 chars + NULL terminating which is why you need to use the function to get the size and to NULL size + 1. ALLEGRO_USTR makes this easier, but I use std::string because my GUI API is backend independent. Agui GUI API -> https://github.com/jmasterx/Agui |
Desmond Taylor
Member #11,943
May 2010
|
Thanks Works a dream. |
Matthew Leverton
Supreme Loser
January 1999
|
Definitely some bizarre code in this thread... ALLEGRO_USTR *foo = al_ustr_new(""); al_ustr_append_chr(foo, unichar); printf("%s", al_cstr(foo)); // to convert to a C string al_draw_ustr(font, color, x,y, 0, foo);
|
Desmond Taylor
Member #11,943
May 2010
|
Thanks, That one works better. I was just about to post this video showing an error I get when rendering buttons afterwards Here is the video anyway http://www.youtube.com/watch?v=M_A_Ty71JlY This is my new case 1 case ALLEGRO_EVENT_KEY_CHAR:
2 {
3 if ( this->event.keyboard.keycode == ALLEGRO_KEY_BACKSPACE )
4 {
5 this->input->set_special_key_state( KEY_STATE_BACKSPACE );
6 }
7 else if ( this->event.keyboard.keycode == ALLEGRO_KEY_ENTER )
8 {
9 this->input->set_special_key_state( KEY_STATE_ENTER );
10 }
11 else if ( this->event.keyboard.keycode == ALLEGRO_KEY_TAB )
12 {
13 this->input->set_special_key_state( KEY_STATE_TAB );
14 }
15 else
16 {
17 ALLEGRO_USTR* ustr = al_ustr_new( "" );
18 al_ustr_append_chr( ustr, this->event.keyboard.unichar );
19 this->input->set_last_repeat_char( al_cstr( ustr ) );
20 this->input->set_special_key_state( KEY_STATE_NONE );
21 al_ustr_free( ustr );
22 }
23 }
24 break;
|
Matthew Leverton
Supreme Loser
January 1999
|
You shouldn't create a new ustr on every key press. Have a single ustr for each text box. Append the new character to it, and draw it to the bitmap. I don't know what your input class is doing, but this is very simple: 1 case ALLEGRO_EVENT_KEY_CHAR:
2 {
3 if ( this->event.keyboard.keycode == ALLEGRO_KEY_BACKSPACE )
4 {
5 // may need to check if the ustr is empty
6 al_ustr_remove_chr(this->ustr, al_ustr_offset(this->ustr, -1));
7 }
8 else if ( this->event.keyboard.keycode == ALLEGRO_KEY_ENTER )
9 {
10 this->input->set_special_key_state( KEY_STATE_ENTER );
11 }
12 else if ( this->event.keyboard.keycode == ALLEGRO_KEY_TAB )
13 {
14 this->input->set_special_key_state( KEY_STATE_TAB );
15 }
16 else
17 {
18 al_ustr_append_chr( this->ustr, this->event.keyboard.unichar );
19 }
20 }
21 break;
Use the various draw_ustr functions to output the text. |
Desmond Taylor
Member #11,943
May 2010
|
I have one event queue that handles everything since it's a simple game to re-create. The input field is a class and the data is stored in the input box due to needing them later on. It's a clone of Endless Online since the server was taken down by the owner. It's not been updated since 2007, the site was last updated 2009 so I'm creating the entire thing again since I used to play that daily Miss it to be honest. Anyway, I am making a clone of his MMORPG |
Thomas Fjellstrom
Member #476
June 2000
|
Desmond Taylor said: The input field is a class and the data is stored in the input box due to needing them later on. Yes, and if you make it an `ALLEGRO_USTR *` instead of a `char *`, you can do as Matthew says, and save the memory allocation and excess copying. -- |
Desmond Taylor
Member #11,943
May 2010
|
Thomas Fjellstrom said: Yes, and if you make it an `ALLEGRO_USTR *` instead of a `char *`, you can do as Matthew says, and save the memory allocation and excess copying. Yes, but I'm too used to std::string functions for appending text ect so it's copied to that. :/ I shall read more about ALLEGRO_USTR* for sure but for now I shall use std::string since I know it better |
|