1 //********************************************************************************************
2 //*
3 //* This file is part of Egoboo.
4 //*
5 //* Egoboo is free software: you can redistribute it and/or modify it
6 //* under the terms of the GNU General Public License as published by
7 //* the Free Software Foundation, either version 3 of the License, or
8 //* (at your option) any later version.
9 //*
10 //* Egoboo is distributed in the hope that it will be useful, but
11 //* WITHOUT ANY WARRANTY; without even the implied warranty of
12 //* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 //* General Public License for more details.
14 //*
15 //* You should have received a copy of the GNU General Public License
16 //* along with Egoboo. If not, see <http://www.gnu.org/licenses/>.
17 //*
18 //********************************************************************************************
19
20 /// @file egoboo_console.c
21 /// @brief Implementation of code for implementing a Quake-like console in Egoboo
22 /// @details
23
24 #include "egoboo_console.inl"
25
26 #include "egoboo_math.inl"
27 #include "egoboo_strutil.h"
28 #include "egoboo_vfs.h"
29
30 #include "extensions/ogl_debug.h"
31 #include "extensions/SDL_extensions.h"
32
33 #include "file_common.h"
34
35 #include <string.h>
36 #include <SDL.h>
37 #include <SDL_opengl.h>
38 #include "egoboo_mem.h"
39
40 //--------------------------------------------------------------------------------------------
41 //--------------------------------------------------------------------------------------------
42 egoboo_console_t * egoboo_console_top = NULL;
43
44 Uint8 scancode_to_ascii[SDLK_LAST];
45 Uint8 scancode_to_ascii_shift[SDLK_LAST];
46
47 //--------------------------------------------------------------------------------------------
48 //--------------------------------------------------------------------------------------------
49
50 static void egoboo_console_add_output( egoboo_console_t * pcon, char * szNew );
51 static void egoboo_console_write( egoboo_console_t * pcon, const char *format, va_list args );
52
53 static SDL_bool egoboo_console_draw( egoboo_console_t * pcon );
54 static SDL_bool egoboo_console_run( egoboo_console_t * pcon );
55
56 //--------------------------------------------------------------------------------------------
57 //--------------------------------------------------------------------------------------------
egoboo_console_stack_unlink(egoboo_console_t * pcon)58 static SDL_bool egoboo_console_stack_unlink( egoboo_console_t * pcon )
59 {
60 SDL_bool retval = SDL_FALSE;
61
62 if ( NULL == pcon ) return retval;
63
64 if ( pcon == egoboo_console_top )
65 {
66 egoboo_console_top = pcon->pnext;
67 retval = SDL_TRUE;
68 }
69 else
70 {
71 egoboo_console_t * ptmp;
72
73 // find the console that points to this one
74 ptmp = egoboo_console_top;
75 while ( NULL != ptmp && NULL != ptmp->pnext )
76 {
77 if ( ptmp->pnext == pcon )
78 {
79 retval = SDL_TRUE;
80 ptmp->pnext = pcon->pnext;
81 break;
82 }
83 ptmp = ptmp->pnext;
84 }
85 }
86
87 return retval;
88 }
89
90 //--------------------------------------------------------------------------------------------
egoboo_console_stack_push_front(egoboo_console_t * pcon)91 static SDL_bool egoboo_console_stack_push_front( egoboo_console_t * pcon )
92 {
93 if ( NULL == pcon ) return SDL_FALSE;
94
95 pcon->pnext = egoboo_console_top;
96 egoboo_console_top = pcon;
97
98 return SDL_TRUE;
99 }
100
101 //--------------------------------------------------------------------------------------------
102 //--------------------------------------------------------------------------------------------
egoboo_console_write(egoboo_console_t * pcon,const char * format,va_list args)103 void egoboo_console_write( egoboo_console_t * pcon, const char *format, va_list args )
104 {
105 char buffer[EGOBOO_CONSOLE_WRITE_LEN] = EMPTY_CSTR;
106
107 if ( NULL != pcon )
108 {
109 vsnprintf( buffer, EGOBOO_CONSOLE_WRITE_LEN - 1, format, args );
110
111 egoboo_console_add_output( pcon, buffer );
112 }
113 }
114
115 //--------------------------------------------------------------------------------------------
egoboo_console_fprint(egoboo_console_t * pcon,const char * format,...)116 void egoboo_console_fprint( egoboo_console_t * pcon, const char *format, ... )
117 {
118 va_list args;
119
120 va_start( args, format );
121 egoboo_console_write( pcon, format, args );
122 va_end( args );
123 }
124
125 //--------------------------------------------------------------------------------------------
egoboo_console_add_output(egoboo_console_t * pcon,char * szNew)126 void egoboo_console_add_output( egoboo_console_t * pcon, char * szNew )
127 {
128 size_t out_len, copy_len;
129 char * src, * dst;
130
131 if ( NULL == pcon ) return;
132
133 // how many characters are we adding?
134 out_len = strlen( szNew );
135
136 // initialize the pointers for the copy operation
137 src = szNew;
138 dst = pcon->output_buffer + pcon->output_carat;
139 copy_len = out_len;
140
141 // check to make sure that the ranges are valid
142 if ( out_len > EGOBOO_CONSOLE_OUTPUT )
143 {
144 // we need to replace the entire output buffer with
145 // a portion of szNew
146
147 size_t offset = out_len - EGOBOO_CONSOLE_OUTPUT - 1;
148
149 // update the copy parameters
150 src = szNew + offset;
151 copy_len = out_len - offset;
152 }
153 else if ( pcon->output_carat + out_len > EGOBOO_CONSOLE_OUTPUT )
154 {
155 // the length of the buffer after adding szNew would be too large
156 // get rid of some of the input buffer and then add szNew
157
158 size_t offset = ( pcon->output_carat + out_len ) - EGOBOO_CONSOLE_OUTPUT - 1;
159
160 // move the memory so that we create some space
161 memmove( pcon->output_buffer, pcon->output_buffer + offset, pcon->output_carat - offset );
162
163 // update the copy parameters
164 pcon->output_carat -= offset;
165 dst = pcon->output_buffer - pcon->output_carat;
166 }
167
168 pcon->output_carat += snprintf( dst, EGOBOO_CONSOLE_OUTPUT - pcon->output_carat, "%s", src );
169 pcon->output_buffer[EGOBOO_CONSOLE_OUTPUT-1] = CSTR_END;
170 }
171
172 //--------------------------------------------------------------------------------------------
egoboo_console_ctor(egoboo_console_t * pcon,SDL_Rect Con_rect,egoboo_console_callback_t pcall,void * data)173 egoboo_console_t * egoboo_console_ctor( egoboo_console_t * pcon, SDL_Rect Con_rect, egoboo_console_callback_t pcall, void * data )
174 {
175 if ( NULL == pcon ) return NULL;
176
177 // reset all the console data
178 memset( pcon, 0, sizeof( *pcon ) );
179
180 // set the console's font
181 pcon->pfont = fnt_loadFont( vfs_resolveReadFilename( "mp_data/pc8x8.fon" ), 12 );
182
183 // set the console's rectangle
184 pcon->rect = Con_rect;
185
186 // register the "run" callback
187 pcon->run_func = pcall;
188 pcon->run_data = data;
189
190 // insert the new console as the top console
191 egoboo_console_stack_push_front( pcon );
192
193 return pcon;
194 }
195
196 //--------------------------------------------------------------------------------------------
egoboo_console_create(egoboo_console_t * pcon,SDL_Rect Con_rect,egoboo_console_callback_t pcall,void * data)197 egoboo_console_t * egoboo_console_create( egoboo_console_t * pcon, SDL_Rect Con_rect, egoboo_console_callback_t pcall, void * data )
198 {
199 SDL_bool local_allocation = SDL_FALSE;
200
201 if ( NULL == pcon )
202 {
203 local_allocation = SDL_TRUE;
204 pcon = EGOBOO_NEW( egoboo_console_t );
205 }
206
207 return egoboo_console_ctor( pcon, Con_rect, pcall, data );
208 }
209
210 //--------------------------------------------------------------------------------------------
egoboo_console_run(egoboo_console_t * pcon)211 SDL_bool egoboo_console_run( egoboo_console_t * pcon )
212 {
213 SDL_bool retval = SDL_FALSE;
214
215 if ( NULL == pcon ) return retval;
216
217 if ( NULL != pcon->run_func )
218 {
219 retval = pcon->run_func( pcon, pcon->run_data );
220 }
221
222 return retval;
223 }
224
225 //--------------------------------------------------------------------------------------------
egoboo_console_dtor(egoboo_console_t * pcon)226 egoboo_console_t * egoboo_console_dtor( egoboo_console_t * pcon )
227 {
228 if ( NULL == pcon ) return NULL;
229
230 fnt_freeFont( pcon->pfont );
231
232 // remove the console from the stack
233 egoboo_console_stack_unlink( pcon );
234
235 return pcon;
236 }
237
238 //--------------------------------------------------------------------------------------------
egoboo_console_destroy(egoboo_console_t ** pcon,SDL_bool do_free)239 SDL_bool egoboo_console_destroy( egoboo_console_t ** pcon, SDL_bool do_free )
240 {
241 if ( NULL == pcon ) return SDL_FALSE;
242
243 if ( NULL == egoboo_console_dtor( *pcon ) ) return SDL_FALSE;
244
245 if ( do_free ) EGOBOO_DELETE( *pcon );
246
247 return SDL_TRUE;
248 }
249
250 //--------------------------------------------------------------------------------------------
egoboo_console_draw_begin()251 void egoboo_console_draw_begin()
252 {
253 // do not use the ATTRIB_PUSH macro, since the glPopAttrib() is in a different function
254 GL_DEBUG( glPushAttrib )( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_VIEWPORT_BIT );
255
256 // don't worry about hidden surfaces
257 GL_DEBUG( glDisable )( GL_DEPTH_TEST ); // GL_ENABLE_BIT
258
259 // draw draw front and back faces of polygons
260 GL_DEBUG( glDisable )( GL_CULL_FACE ); // GL_ENABLE_BIT
261
262 GL_DEBUG( glEnable )( GL_TEXTURE_2D ); // GL_ENABLE_BIT
263
264 GL_DEBUG( glEnable )( GL_BLEND ); // GL_ENABLE_BIT
265 GL_DEBUG( glBlendFunc )( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // GL_COLOR_BUFFER_BIT
266
267 GL_DEBUG( glViewport )( 0, 0, sdl_scr.x, sdl_scr.y ); // GL_VIEWPORT_BIT
268
269 // Set up an ortho projection for the gui to use. Controls are free to modify this
270 // later, but most of them will need this, so it's done by default at the beginning
271 // of a frame
272
273 // store the GL_PROJECTION matrix (this stack has a finite depth, minimum of 32)
274 GL_DEBUG( glMatrixMode )( GL_PROJECTION );
275 GL_DEBUG( glPushMatrix )();
276 GL_DEBUG( glLoadIdentity )();
277 GL_DEBUG( glOrtho )( 0, sdl_scr.x, sdl_scr.y, 0, -1, 1 );
278
279 // store the GL_MODELVIEW matrix (this stack has a finite depth, minimum of 32)
280 GL_DEBUG( glMatrixMode )( GL_MODELVIEW );
281 GL_DEBUG( glPushMatrix )();
282 GL_DEBUG( glLoadIdentity )();
283 }
284
285 //--------------------------------------------------------------------------------------------
egoboo_console_draw_end()286 void egoboo_console_draw_end()
287 {
288 // Restore the GL_PROJECTION matrix
289 GL_DEBUG( glMatrixMode )( GL_PROJECTION );
290 GL_DEBUG( glPopMatrix )();
291
292 // Restore the GL_MODELVIEW matrix
293 GL_DEBUG( glMatrixMode )( GL_MODELVIEW );
294 GL_DEBUG( glPopMatrix )();
295
296 // Re-enable any states disabled by gui_beginFrame
297 // do not use the ATTRIB_POP macro, since the glPushAttrib() is in a different function
298 GL_DEBUG( glPopAttrib )();
299 }
300
301 //--------------------------------------------------------------------------------------------
egoboo_console_draw(egoboo_console_t * pcon)302 SDL_bool egoboo_console_draw( egoboo_console_t * pcon )
303 {
304 char buffer[EGOBOO_CONSOLE_WRITE_LEN] = EMPTY_CSTR;
305 size_t console_line_count;
306 size_t console_line_offsets[1024];
307 size_t console_line_lengths[1024];
308 char * pstr;
309
310 SDL_Rect * pwin;
311 SDL_Surface * surf = SDL_GetVideoSurface();
312
313 if ( NULL == surf || NULL == pcon || !pcon->on ) return SDL_FALSE;
314
315 pwin = &( pcon->rect );
316
317 GL_DEBUG( glDisable )( GL_TEXTURE_2D );
318
319 GL_DEBUG( glColor4f )( 1, 1, 1, 1 );
320 GL_DEBUG( glLineWidth )( 5 );
321 GL_DEBUG( glBegin )( GL_LINE_LOOP );
322 {
323 GL_DEBUG( glVertex2i )( pwin->x, pwin->y );
324 GL_DEBUG( glVertex2i )( pwin->x + pwin->w, pwin->y );
325 GL_DEBUG( glVertex2i )( pwin->x + pwin->w, pwin->y + pwin->h );
326 GL_DEBUG( glVertex2i )( pwin->x, pwin->y + pwin->h );
327 }
328 GL_DEBUG_END();
329 GL_DEBUG( glLineWidth )( 1 );
330
331 GL_DEBUG( glColor4f )( 0, 0, 0, 1 );
332 GL_DEBUG( glBegin )( GL_POLYGON );
333 {
334 GL_DEBUG( glVertex2i )( pwin->x, pwin->y );
335 GL_DEBUG( glVertex2i )( pwin->x + pwin->w, pwin->y );
336 GL_DEBUG( glVertex2i )( pwin->x + pwin->w, pwin->y + pwin->h );
337 GL_DEBUG( glVertex2i )( pwin->x, pwin->y + pwin->h );
338 }
339 GL_DEBUG_END();
340
341 GL_DEBUG( glEnable )( GL_TEXTURE_2D );
342
343 GL_DEBUG( glColor4f )( 1, 1, 1, 1 );
344 ATTRIB_PUSH( __FUNCTION__, GL_SCISSOR_BIT | GL_ENABLE_BIT );
345 {
346 int text_w, text_h, height;
347
348 // make the texture a "null" texture
349 GL_DEBUG( glBindTexture )( GL_TEXTURE_2D, ( GLuint )( ~0 ) );
350
351 // clip the viewport
352 GL_DEBUG( glEnable )( GL_SCISSOR_TEST );
353 GL_DEBUG( glScissor )( pwin->x, surf->h - ( pwin->y + pwin->h ), pwin->w, pwin->h );
354
355 height = pwin->h;
356
357 // draw the current command line
358 buffer[0] = EGOBOO_CONSOLE_PROMPT;
359 buffer[1] = ' ';
360 buffer[2] = CSTR_END;
361
362 strncat( buffer, pcon->buffer, 1022 );
363 buffer[1022] = CSTR_END;
364
365 fnt_getTextSize( pcon->pfont, buffer, &text_w, &text_h );
366 height -= text_h;
367 fnt_drawText( pcon->pfont, NULL, pwin->x, height - text_h, buffer );
368
369 if ( CSTR_END != pcon->output_buffer[0] )
370 {
371 int i;
372
373 // grab the line offsets
374 console_line_count = 0;
375 pstr = pcon->output_buffer;
376 while ( NULL != pstr )
377 {
378 size_t len;
379
380 len = strcspn( pstr, "\n" );
381
382 console_line_offsets[console_line_count] = pstr - pcon->output_buffer;
383 console_line_lengths[console_line_count] = len;
384
385 if ( 0 == len ) break;
386
387 pstr += len + 1;
388 console_line_count++;
389 }
390
391 // draw the last output line and work backwards
392 for ( i = (( int )console_line_count ) - 1; i >= 0 && height > 0 ; i-- )
393 {
394 size_t len = MIN( 1023, console_line_lengths[i] );
395
396 strncpy( buffer, pcon->output_buffer + console_line_offsets[i], len );
397 buffer[len] = CSTR_END;
398
399 fnt_getTextSize( pcon->pfont, buffer, &text_w, &text_h );
400 height -= text_h;
401 fnt_drawText( pcon->pfont, NULL, pwin->x, height - text_h, buffer );
402 }
403 }
404
405 };
406
407 ATTRIB_POP( __FUNCTION__ );
408 return SDL_TRUE;
409 }
410
411 //--------------------------------------------------------------------------------------------
egoboo_console_draw_all()412 void egoboo_console_draw_all()
413 {
414 egoboo_console_t * pcon = egoboo_console_top;
415
416 if ( NULL == pcon ) return;
417
418 egoboo_console_draw_begin();
419 {
420 for ( pcon = egoboo_console_top; NULL != pcon; pcon = pcon->pnext )
421 {
422 egoboo_console_draw( pcon );
423 }
424 }
425 egoboo_console_draw_end();
426 }
427
428 //--------------------------------------------------------------------------------------------
egoboo_console_show(egoboo_console_t * pcon)429 void egoboo_console_show( egoboo_console_t * pcon )
430 {
431 if ( NULL != pcon )
432 {
433 // turn the console on
434 pcon->on = SDL_TRUE;
435 }
436
437 // fix the keyrepeat
438 if ( NULL == egoboo_console_top )
439 {
440 SDL_EnableKeyRepeat( 0, SDL_DEFAULT_REPEAT_INTERVAL );
441 }
442 else
443 {
444 SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
445 }
446 }
447
448 //--------------------------------------------------------------------------------------------
egoboo_console_hide(egoboo_console_t * pcon)449 void egoboo_console_hide( egoboo_console_t * pcon )
450 {
451 if ( NULL != pcon )
452 {
453 // turn the console on
454 pcon->on = SDL_FALSE;
455 }
456
457 // fix the keyrepeat
458 if ( NULL == egoboo_console_top )
459 {
460 SDL_EnableKeyRepeat( 0, SDL_DEFAULT_REPEAT_INTERVAL );
461 }
462 else
463 {
464 SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
465 }
466 }
467
468 //--------------------------------------------------------------------------------------------
egoboo_console_get_saved(egoboo_console_t * pcon)469 const char * egoboo_console_get_saved( egoboo_console_t * pcon )
470 {
471 if ( NULL == pcon ) return "";
472
473 pcon->save_count = CLIP( pcon->save_count, 0, EGOBOO_CONSOLE_LINES );
474 pcon->save_index = CLIP( pcon->save_index, 0, pcon->save_count - 1 );
475
476 return pcon->save_buffer[pcon->save_index];
477 }
478
479 //--------------------------------------------------------------------------------------------
egoboo_console_add_saved(egoboo_console_t * pcon,char * str)480 void egoboo_console_add_saved( egoboo_console_t * pcon, char * str )
481 {
482 if ( NULL == pcon ) return;
483
484 pcon->save_count = CLIP( pcon->save_count, 0, EGOBOO_CONSOLE_LINES );
485
486 if ( pcon->save_count >= EGOBOO_CONSOLE_LINES )
487 {
488 int i;
489
490 // bump all of the saved lines so that we can insert a new one
491 for ( i = 0; i < EGOBOO_CONSOLE_LINES - 1; i++ )
492 {
493 strncpy( pcon->save_buffer[i], pcon->save_buffer[i+1], EGOBOO_CONSOLE_LENGTH );
494 }
495 pcon->save_count--;
496 }
497
498 strncpy( pcon->save_buffer[pcon->save_count], str, EGOBOO_CONSOLE_LENGTH );
499 pcon->save_count++;
500 pcon->save_index = pcon->save_count;
501 }
502
503 //--------------------------------------------------------------------------------------------
egoboo_console_handle_events(SDL_Event * pevt)504 SDL_Event * egoboo_console_handle_events( SDL_Event * pevt )
505 {
506 egoboo_console_t * pcon = egoboo_console_top;
507 SDLKey vkey;
508
509 Uint32 kmod;
510 SDL_bool is_alt, is_shift;
511
512 if ( NULL == pcon || NULL == pevt ) return pevt;
513
514 // only handle keyboard events
515 if ( SDL_KEYDOWN != pevt->type ) return pevt;
516
517 // grab the virtual key code
518 vkey = pevt->key.keysym.sym;
519
520 // get any keymods
521 kmod = SDL_GetModState();
522
523 is_alt = ( SDL_bool )HAS_SOME_BITS( kmod, KMOD_ALT | KMOD_CTRL );
524 is_shift = ( SDL_bool )HAS_SOME_BITS( kmod, KMOD_SHIFT );
525
526 // start the top console
527 if ( !is_alt && !is_shift && SDLK_BACKQUOTE == vkey )
528 {
529 if ( !pcon->on )
530 {
531 pcon->on = SDL_TRUE;
532 pcon->buffer_carat = 0;
533 pcon->buffer[0] = CSTR_END;
534
535 SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_DELAY );
536 return NULL;
537 }
538 };
539
540 // quit the top console. I would like escape, but it is getting confused with the ui "quit" command
541 if ( !is_alt && !is_shift && SDLK_BACKQUOTE == vkey )
542 {
543 if ( pcon->on )
544 {
545 pcon->on = SDL_FALSE;
546 pcon->buffer_carat = 0;
547 pcon->buffer[0] = CSTR_END;
548
549 SDL_EnableKeyRepeat( 0, SDL_DEFAULT_REPEAT_DELAY );
550 return NULL;
551 }
552 };
553
554 // Only grab the keycodes if the terminal is on
555 if ( !pcon->on ) return pevt;
556
557 // handle any terminal commands
558 if ( NULL != pevt && !is_alt && !is_shift )
559 {
560 if ( SDLK_BACKSPACE == vkey )
561 {
562 if ( pcon->buffer_carat > 0 )
563 {
564 pcon->buffer_carat--;
565 }
566 pcon->buffer[pcon->buffer_carat] = CSTR_END;
567
568 pevt = NULL;
569 }
570 else if ( SDLK_UP == vkey )
571 {
572 pcon->save_index--;
573
574 if ( pcon->save_index < 0 )
575 {
576 // after the last command line. blank the line
577 pcon->save_index = 0;
578 pcon->buffer[0] = CSTR_END;
579 pcon->buffer_carat = 0;
580 }
581 else
582 {
583 pcon->save_index = CLIP( pcon->save_index, 0, pcon->save_count - 1 );
584
585 if ( pcon->save_count > 0 )
586 {
587 strncpy( pcon->buffer, pcon->save_buffer[pcon->save_index], SDL_arraysize( pcon->buffer ) );
588 pcon->buffer_carat = strlen( pcon->buffer );
589 pcon->buffer_carat = (( int )pcon->buffer_carat ) - 1;
590 }
591 }
592
593 pevt = NULL;
594 }
595 else if ( SDLK_DOWN == vkey )
596 {
597 pcon->save_index++;
598
599 if ( pcon->save_index >= pcon->save_count )
600 {
601 // before the first command line. blank the line
602 pcon->save_index = pcon->save_count;
603 pcon->buffer[0] = CSTR_END;
604 pcon->buffer_carat = 0;
605 }
606 else
607 {
608 pcon->save_index = CLIP( pcon->save_index, 0, pcon->save_count - 1 );
609
610 if ( pcon->save_count > 0 )
611 {
612 strncpy( pcon->buffer, pcon->save_buffer[pcon->save_index], EGOBOO_CONSOLE_LENGTH - 1 );
613 pcon->buffer_carat = strlen( pcon->buffer );
614 pcon->buffer_carat = (( int )pcon->buffer_carat ) - 1;
615 }
616 }
617
618 pevt = NULL;
619 }
620 else if ( SDLK_LEFT == vkey )
621 {
622 pcon->buffer_carat--;
623 pcon->buffer_carat = CLIP( pcon->buffer_carat, 0, EGOBOO_CONSOLE_LENGTH - 1 );
624
625 pevt = NULL;
626 }
627
628 else if ( SDLK_RIGHT == vkey )
629 {
630 pcon->buffer_carat++;
631 pcon->buffer_carat = CLIP( pcon->buffer_carat, 0, EGOBOO_CONSOLE_LENGTH - 1 );
632
633 pevt = NULL;
634 }
635
636 else if ( SDLK_RETURN == vkey || SDLK_KP_ENTER == vkey )
637 {
638 pcon->buffer[pcon->buffer_carat] = CSTR_END;
639
640 // add this command to the "saved command list"
641 egoboo_console_add_saved( pcon, pcon->buffer );
642
643 // add the command to the output buffer
644 egoboo_console_fprint( pcon, "%c %s\n", EGOBOO_CONSOLE_PROMPT, pcon->buffer );
645
646 // actually execute the command
647 egoboo_console_run( pcon );
648
649 // blank the command line
650 pcon->buffer_carat = 0;
651 pcon->buffer[0] = CSTR_END;
652
653 pevt = NULL;
654 }
655 }
656
657 // handle normal keystrokes
658 if ( NULL != pevt && !is_alt && vkey < SDLK_NUMLOCK )
659 {
660 if ( pcon->buffer_carat < EGOBOO_CONSOLE_LENGTH )
661 {
662 if ( is_shift )
663 {
664 pcon->buffer[pcon->buffer_carat++] = scancode_to_ascii_shift[vkey];
665 }
666 else
667 {
668 pcon->buffer[pcon->buffer_carat++] = scancode_to_ascii[vkey];
669 }
670 pcon->buffer[pcon->buffer_carat] = CSTR_END;
671
672 pevt = NULL;
673 }
674 }
675
676 return pevt;
677 }
678
679 //--------------------------------------------------------------------------------------------
init_scancodes()680 void init_scancodes()
681 {
682 /// @details BB@> initialize the scancode translation
683
684 int i;
685
686 // do the basic translation
687 for ( i = 0; i < SDLK_LAST; i++ )
688 {
689 // SDL uses ascii values for it's virtual scancodes
690 scancode_to_ascii[i] = i;
691 if ( i < 255 )
692 {
693 scancode_to_ascii_shift[i] = toupper( i );
694 }
695 else
696 {
697 scancode_to_ascii_shift[i] = scancode_to_ascii[i];
698 }
699 }
700
701 // fix the keymap
702 scancode_to_ascii_shift[SDLK_1] = '!';
703 scancode_to_ascii_shift[SDLK_2] = '@';
704 scancode_to_ascii_shift[SDLK_3] = '#';
705 scancode_to_ascii_shift[SDLK_4] = '$';
706 scancode_to_ascii_shift[SDLK_5] = '%';
707 scancode_to_ascii_shift[SDLK_6] = '^';
708 scancode_to_ascii_shift[SDLK_7] = '&';
709 scancode_to_ascii_shift[SDLK_8] = '*';
710 scancode_to_ascii_shift[SDLK_9] = '(';
711 scancode_to_ascii_shift[SDLK_0] = ')';
712
713 scancode_to_ascii_shift[SDLK_QUOTE] = '\"';
714 scancode_to_ascii_shift[SDLK_SEMICOLON] = ':';
715 scancode_to_ascii_shift[SDLK_PERIOD] = '>';
716 scancode_to_ascii_shift[SDLK_COMMA] = '<';
717 scancode_to_ascii_shift[SDLK_BACKQUOTE] = '~';
718 scancode_to_ascii_shift[SDLK_MINUS] = '_';
719 scancode_to_ascii_shift[SDLK_EQUALS] = '+';
720 scancode_to_ascii_shift[SDLK_LEFTBRACKET] = '{';
721 scancode_to_ascii_shift[SDLK_RIGHTBRACKET] = '}';
722 scancode_to_ascii_shift[SDLK_BACKSLASH] = '|';
723 scancode_to_ascii_shift[SDLK_SLASH] = '?';
724 }
725