Codebase list libsdl-console / af217bf
Imported Upstream version 1.3 Manuel A. Fernandez Montecelo 12 years ago
19 changed file(s) with 2300 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 /* CON_console.c
1 * Written By: Garrett Banuk <mongoose@mongeese.org>
2 * This is free, just be sure to give me credit when using it
3 * in any of your programs.
4 */
5
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdarg.h>
10 #include "SDL.h"
11 #include "SDL_image.h"
12 #include "CON_console.h"
13 #include "DT_drawtext.h"
14 #include "internal.h"
15
16
17 /* This contains a pointer to the "topmost" console. The console that
18 * is currently taking keyboard input. */
19 static ConsoleInformation *Topmost;
20
21 /* Forward declaration, this functions are only used internally. */
22 static void DrawCommandLine();
23 void Cursor_Left(ConsoleInformation *console);
24 void Cursor_Right(ConsoleInformation *console);
25 void Cursor_Home(ConsoleInformation *console);
26 void Cursor_End(ConsoleInformation *console);
27 void Cursor_Del(ConsoleInformation *console);
28 void Cursor_BSpace(ConsoleInformation *console);
29 void Cursor_Add(ConsoleInformation *console, SDL_Event *event);
30
31 void Clear_Command(ConsoleInformation *console);
32 void Clear_History(ConsoleInformation *console);
33
34 void Command_Up(ConsoleInformation *console);
35 void Command_Down(ConsoleInformation *console);
36
37
38 /* Takes keys from the keyboard and inputs them to the console */
39 void CON_Events(SDL_Event *event) {
40
41 if(Topmost != NULL && event->type == SDL_KEYDOWN) { switch (event->key.keysym.sym) {
42 case SDLK_PAGEUP:
43 Topmost->ConsoleScrollBack += CON_LINE_SCROLL;
44 if(Topmost->ConsoleScrollBack > Topmost->LineBuffer-1)
45 Topmost->ConsoleScrollBack = Topmost->LineBuffer-1;
46
47 CON_UpdateConsole(Topmost);
48 break;
49 case SDLK_PAGEDOWN:
50 Topmost->ConsoleScrollBack -= CON_LINE_SCROLL;
51 if(Topmost->ConsoleScrollBack < 0)
52 Topmost->ConsoleScrollBack = 0;
53 CON_UpdateConsole(Topmost);
54 break;
55 case SDLK_HOME:
56 if(event->key.keysym.mod & KMOD_SHIFT) {
57 Topmost->ConsoleScrollBack = Topmost->LineBuffer-1;
58 CON_UpdateConsole(Topmost);
59 } else {
60 Cursor_Home(Topmost);
61 }
62 break;
63 case SDLK_END:
64 if(event->key.keysym.mod & KMOD_SHIFT) {
65 Topmost->ConsoleScrollBack = 0;
66 CON_UpdateConsole(Topmost);
67 } else {
68 Cursor_End(Topmost);
69 }
70 break;
71 case SDLK_UP:
72 Command_Up(Topmost);
73 break;
74 case SDLK_DOWN:
75 Command_Down(Topmost);
76 break;
77 case SDLK_LEFT:
78 Cursor_Left(Topmost);
79 break;
80 case SDLK_RIGHT:
81 Cursor_Right(Topmost);
82 break;
83 case SDLK_BACKSPACE:
84 Cursor_BSpace(Topmost);
85 break;
86 case SDLK_DELETE:
87 Cursor_Del(Topmost);
88 break;
89 case SDLK_INSERT:
90 if(Topmost->InsMode)
91 Topmost->InsMode = 0;
92 else
93 Topmost->InsMode = 1;
94 break;
95 case SDLK_TAB:
96 CON_TabCompletion(Topmost);
97 break;
98 case SDLK_RETURN:
99 if(strlen(Topmost->Command) > 0) {
100 CON_NewLineCommand(Topmost);
101
102 // copy the input into the past commands strings
103 strcpy(Topmost->CommandLines[0], Topmost->Command);
104
105 // display the command including the prompt
106 CON_Out(Topmost, "%s%s", Topmost->Prompt, Topmost->Command);
107
108 CON_CommandExecute(Topmost);
109
110 Clear_Command(Topmost);
111 Topmost->CommandScrollBack = -1;
112 }
113 CON_UpdateConsole(Topmost);
114 break;
115 case SDLK_a:
116 if(event->key.keysym.mod & KMOD_CTRL) {
117 Cursor_Home(Topmost);
118 break;
119 }
120 case SDLK_e:
121 if(event->key.keysym.mod & KMOD_CTRL) {
122 Cursor_End(Topmost);
123 break;
124 }
125 case SDLK_c:
126 if(event->key.keysym.mod & KMOD_CTRL) {
127 Clear_Command(Topmost);
128 break;
129 }
130 case SDLK_l:
131 if(event->key.keysym.mod & KMOD_CTRL) {
132 Clear_History(Topmost);
133 CON_UpdateConsole(Topmost);
134 break;
135 }
136 default:
137 if(Topmost->InsMode)
138 Cursor_Add(Topmost, event);
139 else {
140 Cursor_Add(Topmost, event);
141 Cursor_Del(Topmost);
142 }
143 }
144 }
145 }
146
147 /* CON_SetAlphaGL() -- sets the alpha channel of an SDL_Surface to the
148 * specified value. Preconditions: the surface in question is RGBA.
149 * 0 <= a <= 255, where 0 is transparent and 255 is opaque. */
150 void CON_SetAlphaGL(SDL_Surface *s, int alpha)
151 {
152 Uint8 val;
153 int x, y, w, h;
154 Uint32 pixel;
155 Uint8 r, g, b, a;
156 SDL_PixelFormat *format;
157 static char errorPrinted = 0;
158
159
160 /* debugging assertions -- these slow you down, but hey, crashing sucks */
161 if(!s)
162 {
163 PRINT_ERROR("NULL Surface passed to CON_SetAlphaGL\n");
164 return;
165 }
166
167 /* clamp alpha value to 0...255 */
168 if(alpha < SDL_ALPHA_TRANSPARENT)
169 val = SDL_ALPHA_TRANSPARENT;
170 else if(alpha > SDL_ALPHA_OPAQUE)
171 val = SDL_ALPHA_OPAQUE;
172 else
173 val = alpha;
174
175 /* loop over alpha channels of each pixel, setting them appropriately. */
176 w = s->w;
177 h = s->h;
178 format = s->format;
179 switch (format->BytesPerPixel)
180 {
181 case 2:
182 /* 16-bit surfaces don't seem to support alpha channels. */
183 if(!errorPrinted)
184 {
185 errorPrinted = 1;
186 PRINT_ERROR("16-bit SDL surfaces do not support alpha-blending under OpenGL.\n");
187 }
188 break;
189 case 4:
190 {
191 /* we can do this very quickly in 32-bit mode. 24-bit is more
192 * difficult. And since 24-bit mode is reall the same as 32-bit,
193 * so it usually ends up taking this route too. Win! Unroll loop
194 * and use pointer arithmetic for extra speed. */
195 int numpixels = h * (w << 2);
196 Uint8 *pix = (Uint8 *) (s->pixels);
197 Uint8 *last = pix + numpixels;
198 Uint8 *pixel;
199 if((numpixels & 0x7) == 0)
200 for(pixel = pix + 3; pixel < last; pixel += 32)
201 *pixel = *(pixel + 4) = *(pixel + 8) = *(pixel + 12) =
202 *(pixel + 16) = *(pixel + 20) = *(pixel + 24) = *(pixel + 28) = val;
203 else
204 for(pixel = pix + 3; pixel < last; pixel += 4)
205 *pixel = val;
206 break;
207 }
208 default:
209 /* we have no choice but to do this slowly. <sigh> */
210 for(y = 0; y < h; ++y)
211 for(x = 0; x < w; ++x)
212 {
213 char print = 0;
214 /* Lock the surface for direct access to the pixels */
215 if(SDL_MUSTLOCK(s) && SDL_LockSurface(s) < 0)
216 {
217 PRINT_ERROR("Can't lock surface: ");
218 fprintf(stderr, "%s\n", SDL_GetError());
219 return;
220 }
221 pixel = DT_GetPixel(s, x, y);
222 if(x == 0 && y == 0)
223 print = 1;
224 SDL_GetRGBA(pixel, format, &r, &g, &b, &a);
225 pixel = SDL_MapRGBA(format, r, g, b, val);
226 SDL_GetRGBA(pixel, format, &r, &g, &b, &a);
227 DT_PutPixel(s, x, y, pixel);
228
229 /* unlock surface again */
230 if(SDL_MUSTLOCK(s))
231 SDL_UnlockSurface(s);
232 }
233 break;
234 }
235 }
236
237
238 /* Updates the console buffer */
239 void CON_UpdateConsole(ConsoleInformation *console)
240 {
241 int loop;
242 int loop2;
243 int Screenlines = console->ConsoleSurface->h / DT_FontHeight(console->FontNumber);
244 SDL_Rect DestRect;
245 BitFont *CurrentFont = DT_FontPointer(console->FontNumber);
246
247
248
249 SDL_FillRect(console->ConsoleSurface, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, console->ConsoleAlpha));
250
251 if(console->OutputScreen->flags & SDL_OPENGLBLIT)
252 SDL_SetAlpha(console->ConsoleSurface, 0, SDL_ALPHA_OPAQUE);
253
254 /* draw the background image if there is one */
255 if(console->BackgroundImage)
256 {
257 DestRect.x = console->BackX;
258 DestRect.y = console->BackY;
259 DestRect.w = console->BackgroundImage->w;
260 DestRect.h = console->BackgroundImage->h;
261 SDL_BlitSurface(console->BackgroundImage, NULL, console->ConsoleSurface, &DestRect);
262 }
263
264 /* Draw the text from the back buffers, calculate in the scrollback from the user
265 * this is a normal SDL software-mode blit, so we need to temporarily set the ColorKey
266 * for the font, and then clear it when we're done.
267 */
268 if((console->OutputScreen->flags & SDL_OPENGLBLIT) && (console->OutputScreen->format->BytesPerPixel > 2))
269 {
270 Uint32 *pix = (Uint32 *) (CurrentFont->FontSurface->pixels);
271 SDL_SetColorKey(CurrentFont->FontSurface, SDL_SRCCOLORKEY, *pix);
272 }
273
274
275 //now draw text from last but second line to top
276 for(loop = 0; loop < Screenlines-1 && loop < console->LineBuffer - console->ConsoleScrollBack; loop++) {
277 if(console->ConsoleScrollBack != 0 && loop == 0)
278 for(loop2 = 0; loop2 < (console->VChars / 5) + 1; loop2++)
279 DT_DrawText(CON_SCROLL_INDICATOR, console->ConsoleSurface, console->FontNumber, CON_CHAR_BORDER + (loop2*5*DT_FontWidth(console->FontNumber)), (Screenlines - loop - 2) * DT_FontHeight(console->FontNumber));
280 else
281 DT_DrawText(console->ConsoleLines[console->ConsoleScrollBack + loop], console->ConsoleSurface, console->FontNumber, CON_CHAR_BORDER, (Screenlines - loop - 2) * DT_FontHeight(console->FontNumber));
282 }
283
284 if(console->OutputScreen->flags & SDL_OPENGLBLIT)
285 SDL_SetColorKey(CurrentFont->FontSurface, 0, 0);
286 }
287
288 /* Draws the console buffer to the screen */
289 void CON_DrawConsole(ConsoleInformation *console)
290 {
291 SDL_Rect DestRect;
292
293
294 /* Update the command line since it has a blinking cursor */
295 if(Topmost) DrawCommandLine();
296
297 /* before drawing, make sure the alpha channel of the console surface is set
298 * properly. (sigh) I wish we didn't have to do this every frame... */
299 if(console->OutputScreen->flags & SDL_OPENGLBLIT)
300 CON_SetAlphaGL(console->ConsoleSurface, console->ConsoleAlpha);
301
302 /* Setup the rect the console is being blitted into based on the output screen */
303 DestRect.x = console->DispX;
304 DestRect.y = console->DispY;
305 DestRect.w = console->ConsoleSurface->w;
306 DestRect.h = console->ConsoleSurface->h;
307
308 SDL_BlitSurface(console->ConsoleSurface, NULL, console->OutputScreen, &DestRect);
309
310 if(console->OutputScreen->flags & SDL_OPENGLBLIT)
311 SDL_UpdateRects(console->OutputScreen, 1, &DestRect);
312 }
313
314
315 /* Initializes the console */
316 ConsoleInformation *CON_Init(const char *FontName, SDL_Surface *DisplayScreen, int lines, SDL_Rect rect)
317 {
318 int loop;
319 SDL_Surface *Temp;
320 ConsoleInformation *newinfo;
321
322
323 /* Create a new console struct and init it. */
324 if((newinfo = (ConsoleInformation *) malloc(sizeof(ConsoleInformation))) == NULL)
325 {
326 PRINT_ERROR("Could not allocate the space for a new console info struct.\n");
327 return NULL;
328 }
329 newinfo->ConsoleLines = NULL;
330 newinfo->CommandLines = NULL;
331 newinfo->TotalConsoleLines = 0;
332 newinfo->ConsoleScrollBack = 0;
333 newinfo->TotalCommands = 0;
334 newinfo->BackgroundImage = NULL;
335 newinfo->ConsoleAlpha = SDL_ALPHA_OPAQUE;
336 newinfo->Offset = 0;
337 newinfo->InsMode = 1;
338 newinfo->CursorPos = 0;
339 newinfo->CommandScrollBack = 0;
340 newinfo->OutputScreen = DisplayScreen;
341 newinfo->Prompt = CON_DEFAULT_PROMPT;
342
343 /* Load the consoles font */
344 if(-1 == (newinfo->FontNumber = DT_LoadFont(FontName, TRANS_FONT)))
345 {
346 PRINT_ERROR("Could not load the font ");
347 fprintf(stderr, "\"%s\" for the console!\n", FontName);
348 return NULL;
349 }
350
351 /* make sure that the size of the console is valid */
352 if(rect.w > newinfo->OutputScreen->w || rect.w < DT_FontWidth(newinfo->FontNumber) * 32)
353 rect.w = newinfo->OutputScreen->w;
354 if(rect.h > newinfo->OutputScreen->h || rect.h < DT_FontHeight(newinfo->FontNumber))
355 rect.h = newinfo->OutputScreen->h;
356 if(rect.x < 0 || rect.x > newinfo->OutputScreen->w - rect.w)
357 newinfo->DispX = 0;
358 else
359 newinfo->DispX = rect.x;
360 if(rect.y < 0 || rect.y > newinfo->OutputScreen->h - rect.h)
361 newinfo->DispY = 0;
362 else
363 newinfo->DispY = rect.y;
364
365 /* load the console surface */
366 Temp = SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, newinfo->OutputScreen->format->BitsPerPixel, 0, 0, 0, 0);
367 if(Temp == NULL)
368 {
369 PRINT_ERROR("Couldn't create the ConsoleSurface\n");
370 return NULL;
371 }
372 newinfo->ConsoleSurface = SDL_DisplayFormat(Temp);
373 SDL_FreeSurface(Temp);
374 SDL_FillRect(newinfo->ConsoleSurface, NULL, SDL_MapRGBA(newinfo->ConsoleSurface->format, 0, 0, 0, newinfo->ConsoleAlpha));
375
376 /* Load the dirty rectangle for user input */
377 Temp = SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, DT_FontHeight(newinfo->FontNumber), newinfo->OutputScreen->format->BitsPerPixel, 0, 0, 0, SDL_ALPHA_OPAQUE);
378 if(Temp == NULL)
379 {
380 PRINT_ERROR("Couldn't create the InputBackground\n");
381 return NULL;
382 }
383 newinfo->InputBackground = SDL_DisplayFormat(Temp);
384 SDL_FreeSurface(Temp);
385 SDL_FillRect(newinfo->InputBackground, NULL, SDL_MapRGBA(newinfo->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE));
386
387 /* calculate the number of visible characters in the command line */
388 newinfo->VChars = (rect.w - CON_CHAR_BORDER) / DT_FontWidth(newinfo->FontNumber);
389 if(newinfo->VChars > CON_CHARS_PER_LINE) newinfo->VChars = CON_CHARS_PER_LINE;
390
391 /* We would like to have a minumum # of lines to guarentee we don't create a memory error */
392 if(rect.h / DT_FontHeight(newinfo->FontNumber) > lines)
393 newinfo->LineBuffer = rect.h / DT_FontHeight(newinfo->FontNumber);
394 else
395 newinfo->LineBuffer = lines;
396
397
398 newinfo->ConsoleLines = (char **)malloc(sizeof(char *) * newinfo->LineBuffer);
399 newinfo->CommandLines = (char **)malloc(sizeof(char *) * newinfo->LineBuffer);
400 for(loop = 0; loop <= newinfo->LineBuffer - 1; loop++)
401 {
402 newinfo->ConsoleLines[loop] = (char *)calloc(CON_CHARS_PER_LINE, sizeof(char));
403 newinfo->CommandLines[loop] = (char *)calloc(CON_CHARS_PER_LINE, sizeof(char));
404 }
405 memset(newinfo->Command, 0, CON_CHARS_PER_LINE);
406 memset(newinfo->LCommand, 0, CON_CHARS_PER_LINE);
407 memset(newinfo->RCommand, 0, CON_CHARS_PER_LINE);
408 memset(newinfo->VCommand, 0, CON_CHARS_PER_LINE);
409
410
411 CON_Out(newinfo, "Console initialised.");
412 CON_NewLineConsole(newinfo);
413 CON_ListCommands(newinfo);
414
415 return newinfo;
416 }
417
418 /* Frees all the memory loaded by the console */
419 void CON_Destroy(ConsoleInformation *console)
420 {
421 DT_DestroyDrawText();
422 CON_Free(console);
423 }
424
425 /* Frees all the memory loaded by the console */
426 void CON_Free(ConsoleInformation *console)
427 {
428 int i;
429
430
431 CON_DestroyCommands();
432 for(i = 0; i <= console->LineBuffer - 1; i++)
433 {
434 free(console->ConsoleLines[i]);
435 free(console->CommandLines[i]);
436 }
437 free(console->ConsoleLines);
438 free(console->CommandLines);
439
440 console->ConsoleLines = NULL;
441 console->CommandLines = NULL;
442 }
443
444
445 /* Increments the console lines */
446 void CON_NewLineConsole(ConsoleInformation *console)
447 {
448 int loop;
449 char *temp = console->ConsoleLines[console->LineBuffer - 1];
450
451
452 for(loop = console->LineBuffer - 1; loop > 0; loop--)
453 console->ConsoleLines[loop] = console->ConsoleLines[loop - 1];
454
455 console->ConsoleLines[0] = temp;
456
457 memset(console->ConsoleLines[0], 0, CON_CHARS_PER_LINE);
458 if(console->TotalConsoleLines < console->LineBuffer - 1)
459 console->TotalConsoleLines++;
460
461 //Now adjust the ConsoleScrollBack
462 //dont scroll if not at bottom
463 if(console->ConsoleScrollBack != 0)
464 console->ConsoleScrollBack++;
465 //boundaries
466 if(console->ConsoleScrollBack > console->LineBuffer-1)
467 console->ConsoleScrollBack = console->LineBuffer-1;
468
469 }
470
471
472 /* Increments the command lines */
473 void CON_NewLineCommand(ConsoleInformation *console)
474 {
475 int loop;
476 char *temp = console->CommandLines[console->LineBuffer - 1];
477
478
479 for(loop = console->LineBuffer - 1; loop > 0; loop--)
480 console->CommandLines[loop] = console->CommandLines[loop - 1];
481
482 console->CommandLines[0] = temp;
483
484 memset(console->CommandLines[0], 0, CON_CHARS_PER_LINE);
485 if(console->TotalCommands < console->LineBuffer - 1)
486 console->TotalCommands++;
487 }
488
489 /* Draws the command line the user is typing in to the screen */
490 /* completely rewritten by C.Wacha */
491 static void DrawCommandLine()
492 {
493 SDL_Rect rect;
494 int x;
495 int commandbuffer = Topmost->VChars - strlen(Topmost->Prompt)-1; // -1 to make cursor visible
496
497 BitFont *CurrentFont = DT_FontPointer(Topmost->FontNumber);
498 static Uint32 LastBlinkTime = 0; /* Last time the consoles cursor blinked */
499 static int LastCursorPos = 0; // Last Cursor Position
500 static int Blink = 0; /* Is the cursor currently blinking */
501
502 //Concatenate the left and right side to command
503 strcpy(Topmost->Command, Topmost->LCommand);
504 strncat(Topmost->Command, Topmost->RCommand, strlen(Topmost->RCommand));
505
506 //calculate display offset from current cursor position
507 if(Topmost->Offset < Topmost->CursorPos - commandbuffer)
508 Topmost->Offset = Topmost->CursorPos - commandbuffer;
509 if(Topmost->Offset > Topmost->CursorPos)
510 Topmost->Offset = Topmost->CursorPos;
511
512 //first add prompt to visible part
513 strcpy(Topmost->VCommand, Topmost->Prompt);
514
515 //then add the visible part of the command
516 strncat(Topmost->VCommand, &Topmost->Command[Topmost->Offset], strlen(&Topmost->Command[Topmost->Offset]));
517
518 //now display the result
519
520 //once again we're drawing text, so in OpenGL context we need to temporarily set up
521 //software-mode transparency.
522 if(Topmost->OutputScreen->flags & SDL_OPENGLBLIT) {
523 Uint32 *pix = (Uint32 *) (CurrentFont->FontSurface->pixels);
524 SDL_SetColorKey(CurrentFont->FontSurface, SDL_SRCCOLORKEY, *pix);
525 }
526
527 //first of all restore InputBackground
528 rect.x = 0;
529 rect.y = Topmost->ConsoleSurface->h - DT_FontHeight(Topmost->FontNumber);
530 rect.w = Topmost->InputBackground->w;
531 rect.h = Topmost->InputBackground->h;
532 SDL_BlitSurface(Topmost->InputBackground, NULL, Topmost->ConsoleSurface, &rect);
533
534 //now add the text
535 DT_DrawText(Topmost->VCommand, Topmost->ConsoleSurface, Topmost->FontNumber, CON_CHAR_BORDER, Topmost->ConsoleSurface->h - DT_FontHeight(Topmost->FontNumber));
536
537 //at last add the cursor
538 //check if the blink period is over
539 if(SDL_GetTicks() > LastBlinkTime) {
540 LastBlinkTime = SDL_GetTicks() + CON_BLINK_RATE;
541 if(Blink)
542 Blink = 0;
543 else
544 Blink = 1;
545 }
546
547 //check if cursor has moved - if yes display cursor anyway
548 if(Topmost->CursorPos != LastCursorPos) {
549 LastCursorPos = Topmost->CursorPos;
550 LastBlinkTime = SDL_GetTicks() + CON_BLINK_RATE;
551 Blink = 1;
552 }
553
554 if(Blink) {
555 x = CON_CHAR_BORDER + DT_FontWidth(Topmost->FontNumber) * (Topmost->CursorPos - Topmost->Offset + strlen(Topmost->Prompt));
556 if(Topmost->InsMode)
557 DT_DrawText(CON_INS_CURSOR, Topmost->ConsoleSurface, Topmost->FontNumber, x, Topmost->ConsoleSurface->h - DT_FontHeight(Topmost->FontNumber));
558 else
559 DT_DrawText(CON_OVR_CURSOR, Topmost->ConsoleSurface, Topmost->FontNumber, x, Topmost->ConsoleSurface->h - DT_FontHeight(Topmost->FontNumber));
560 }
561
562
563 if(Topmost->OutputScreen->flags & SDL_OPENGLBLIT) {
564 SDL_SetColorKey(CurrentFont->FontSurface, 0, 0);
565 }
566 }
567
568 /* Outputs text to the console (in game and stdout), up to CON_CHARS_PER_LINE chars can be entered */
569 void CON_Out(ConsoleInformation *console, const char *str, ...) {
570 va_list marker;
571 //keep some space free for stuff like CON_Out(console, "blablabla %s", console->Command);
572 char temp[CON_CHARS_PER_LINE + 128];
573 char* ptemp = temp;
574
575 va_start(marker, str);
576 vsnprintf(temp, CON_CHARS_PER_LINE + 127, str, marker);
577 va_end(marker);
578
579 if(console->ConsoleLines) {
580 while(strlen(ptemp) > console->VChars) {
581 CON_NewLineConsole(console);
582 strncpy(console->ConsoleLines[0], ptemp, console->VChars);
583 console->ConsoleLines[0][console->VChars] = '\0';
584 ptemp = &ptemp[console->VChars];
585 }
586 CON_NewLineConsole(console);
587 strncpy(console->ConsoleLines[0], ptemp, console->VChars);
588 console->ConsoleLines[0][console->VChars] = '\0';
589 CON_UpdateConsole(console);
590 }
591
592 /* And print to stdout */
593 printf("%s\n", temp);
594 }
595
596
597 /* Sets the alpha level of the console, 0 turns off alpha blending */
598 void CON_Alpha(ConsoleInformation *console, unsigned char alpha)
599 {
600 /* store alpha as state! */
601 console->ConsoleAlpha = alpha;
602
603 if((console->OutputScreen->flags & SDL_OPENGLBLIT) == 0) {
604 if(alpha == 0)
605 SDL_SetAlpha(console->ConsoleSurface, 0, alpha);
606 else
607 SDL_SetAlpha(console->ConsoleSurface, SDL_SRCALPHA, alpha);
608 }
609
610 CON_UpdateConsole(console);
611 }
612
613
614 /* Adds background image to the console, x and y based on consoles x and y */
615 int CON_Background(ConsoleInformation *console, const char *image, int x, int y)
616 {
617 SDL_Surface *temp;
618 SDL_Rect backgroundsrc, backgrounddest;
619
620
621 /* Free the background from the console */
622 if(image == NULL) {
623 if(console->BackgroundImage ==NULL)
624 SDL_FreeSurface(console->BackgroundImage);
625 console->BackgroundImage = NULL;
626 SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE));
627 return 0;
628 }
629
630 /* Load a new background */
631 temp = IMG_Load(image);
632 if(!temp) {
633 CON_Out(console, "Cannot load background %s.", image);
634 return 1;
635 }
636
637 console->BackgroundImage = SDL_DisplayFormat(temp);
638 SDL_FreeSurface(temp);
639 console->BackX = x;
640 console->BackY = y;
641
642 backgroundsrc.x = 0;
643 backgroundsrc.y = console->ConsoleSurface->h - DT_FontHeight(console->FontNumber) - console->BackY;
644 backgroundsrc.w = console->BackgroundImage->w;
645 backgroundsrc.h = console->InputBackground->h;
646
647 backgrounddest.x = console->BackX;
648 backgrounddest.y = 0;
649 backgrounddest.w = console->BackgroundImage->w;
650 backgrounddest.h = DT_FontHeight(console->FontNumber);
651
652 SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE));
653 SDL_BlitSurface(console->BackgroundImage, &backgroundsrc, console->InputBackground, &backgrounddest);
654
655 return 0;
656 }
657
658 /* takes a new x and y of the top left of the console window */
659 void CON_Position(ConsoleInformation *console, int x, int y)
660 {
661 if(x < 0 || x > console->OutputScreen->w - console->ConsoleSurface->w)
662 console->DispX = 0;
663 else
664 console->DispX = x;
665
666 if(y < 0 || y > console->OutputScreen->h - console->ConsoleSurface->h)
667 console->DispY = 0;
668 else
669 console->DispY = y;
670 }
671
672 /* resizes the console, has to reset alot of stuff
673 * returns 1 on error */
674 int CON_Resize(ConsoleInformation *console, SDL_Rect rect)
675 {
676 SDL_Surface *Temp;
677 SDL_Rect backgroundsrc, backgrounddest;
678
679
680 /* make sure that the size of the console is valid */
681 if(rect.w > console->OutputScreen->w || rect.w < DT_FontWidth(console->FontNumber) * 32)
682 rect.w = console->OutputScreen->w;
683 if(rect.h > console->OutputScreen->h || rect.h < DT_FontHeight(console->FontNumber))
684 rect.h = console->OutputScreen->h;
685 if(rect.x < 0 || rect.x > console->OutputScreen->w - rect.w)
686 console->DispX = 0;
687 else
688 console->DispX = rect.x;
689 if(rect.y < 0 || rect.y > console->OutputScreen->h - rect.h)
690 console->DispY = 0;
691 else
692 console->DispY = rect.y;
693
694 /* load the console surface */
695 SDL_FreeSurface(console->ConsoleSurface);
696 Temp = SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, rect.h, console->OutputScreen->format->BitsPerPixel, 0, 0, 0, 0);
697 if(Temp == NULL)
698 {
699 PRINT_ERROR("Couldn't create the console->ConsoleSurface\n");
700 return 1;
701 }
702 console->ConsoleSurface = SDL_DisplayFormat(Temp);
703 SDL_FreeSurface(Temp);
704
705 /* Load the dirty rectangle for user input */
706 SDL_FreeSurface(console->InputBackground);
707 Temp = SDL_CreateRGBSurface(SDL_SWSURFACE, rect.w, DT_FontHeight(console->FontNumber), console->OutputScreen->format->BitsPerPixel, 0, 0, 0, 0);
708 if(Temp == NULL)
709 {
710 PRINT_ERROR("Couldn't create the input background\n");
711 return 1;
712 }
713 console->InputBackground = SDL_DisplayFormat(Temp);
714 SDL_FreeSurface(Temp);
715
716 /* Now reset some stuff dependent on the previous size */
717 console->ConsoleScrollBack = 0;
718
719 /* Reload the background image (for the input text area) in the console */
720 if(console->BackgroundImage)
721 {
722 backgroundsrc.x = 0;
723 backgroundsrc.y = console->ConsoleSurface->h - DT_FontHeight(console->FontNumber) - console->BackY;
724 backgroundsrc.w = console->BackgroundImage->w;
725 backgroundsrc.h = console->InputBackground->h;
726
727 backgrounddest.x = console->BackX;
728 backgrounddest.y = 0;
729 backgrounddest.w = console->BackgroundImage->w;
730 backgrounddest.h = DT_FontHeight(console->FontNumber);
731
732 SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE));
733 SDL_BlitSurface(console->BackgroundImage, &backgroundsrc, console->InputBackground, &backgrounddest);
734 }
735
736 return 0;
737 }
738
739 /* Sets the topmost console for input */
740 void CON_Topmost(ConsoleInformation *console) {
741 SDL_Rect rect;
742
743 // Make sure the blinking cursor is gone
744 if(Topmost) {
745 rect.x = 0;
746 rect.y = Topmost->ConsoleSurface->h - DT_FontHeight(Topmost->FontNumber);
747 rect.w = Topmost->InputBackground->w;
748 rect.h = Topmost->InputBackground->h;
749 SDL_BlitSurface(Topmost->InputBackground, NULL, Topmost->ConsoleSurface, &rect);
750 DT_DrawText(Topmost->ConsoleLines[0], Topmost->ConsoleSurface, Topmost->FontNumber, CON_CHAR_BORDER, Topmost->ConsoleSurface->h - DT_FontHeight(Topmost->FontNumber));
751 }
752 Topmost = console;
753 }
754
755 void CON_SetPrompt(ConsoleInformation *console, char* newprompt) {
756 //check length so we can still see at least 1 char :-)
757 if(strlen(newprompt) < console->VChars)
758 console->Prompt = strdup(newprompt);
759 else
760 CON_Out(console, "prompt too long. (max. %i chars)", console->VChars - 1);
761 }
762
763
764 void Cursor_Left(ConsoleInformation *console){
765 char temp[CON_CHARS_PER_LINE];
766
767 if(Topmost->CursorPos > 0) {
768 Topmost->CursorPos--;
769 strcpy(temp, Topmost->RCommand);
770 strcpy(Topmost->RCommand, &Topmost->LCommand[strlen(Topmost->LCommand)-1]);
771 strcat(Topmost->RCommand, temp);
772 Topmost->LCommand[strlen(Topmost->LCommand)-1] = '\0';
773 //CON_Out(Topmost, "L:%s, R:%s", Topmost->LCommand, Topmost->RCommand);
774 }
775 }
776
777 void Cursor_Right(ConsoleInformation *console){
778 char temp[CON_CHARS_PER_LINE];
779
780 if(Topmost->CursorPos < strlen(Topmost->Command)) {
781 Topmost->CursorPos++;
782 strncat(Topmost->LCommand, Topmost->RCommand, 1);
783 strcpy(temp, Topmost->RCommand);
784 strcpy(Topmost->RCommand, &temp[1]);
785 //CON_Out(Topmost, "L:%s, R:%s", Topmost->LCommand, Topmost->RCommand);
786 }
787 }
788
789 void Cursor_Home(ConsoleInformation *console){
790 char temp[CON_CHARS_PER_LINE];
791
792 Topmost->CursorPos = 0;
793 strcpy(temp, Topmost->RCommand);
794 strcpy(Topmost->RCommand, Topmost->LCommand);
795 strncat(Topmost->RCommand, temp, strlen(temp));
796 memset(Topmost->LCommand, 0, CON_CHARS_PER_LINE);
797 }
798
799 void Cursor_End(ConsoleInformation *console){
800 Topmost->CursorPos = strlen(Topmost->Command);
801 strncat(Topmost->LCommand, Topmost->RCommand, strlen(Topmost->RCommand));
802 memset(Topmost->RCommand, 0, CON_CHARS_PER_LINE);
803 }
804
805 void Cursor_Del(ConsoleInformation *console) {
806 char temp[CON_CHARS_PER_LINE];
807
808 if(strlen(Topmost->RCommand) > 0) {
809 strcpy(temp, Topmost->RCommand);
810 strcpy(Topmost->RCommand, &temp[1]);
811 }
812 }
813
814 void Cursor_BSpace(ConsoleInformation *console) {
815 if(Topmost->CursorPos > 0) {
816 Topmost->CursorPos--;
817 Topmost->Offset--;
818 if(Topmost->Offset < 0) Topmost->Offset = 0;
819 Topmost->LCommand[strlen(Topmost->LCommand)-1] = '\0';
820 }
821 }
822
823 void Cursor_Add(ConsoleInformation *console, SDL_Event *event) {
824 if(strlen(Topmost->Command) < CON_CHARS_PER_LINE - 1 && event->key.keysym.unicode) {
825 Topmost->CursorPos++;
826 Topmost->LCommand[strlen(Topmost->LCommand)] = (char)event->key.keysym.unicode;
827 Topmost->LCommand[strlen(Topmost->LCommand)] = '\0';
828 }
829 }
830
831 void Clear_Command(ConsoleInformation *console) {
832 Topmost->CursorPos = 0;
833 memset(Topmost->VCommand, 0, CON_CHARS_PER_LINE);
834 memset(Topmost->Command, 0, CON_CHARS_PER_LINE);
835 memset(Topmost->LCommand, 0, CON_CHARS_PER_LINE);
836 memset(Topmost->RCommand, 0, CON_CHARS_PER_LINE);
837 }
838
839 void Clear_History(ConsoleInformation *console) {
840 int loop;
841
842 for(loop = 0; loop <= console->LineBuffer - 1; loop++)
843 memset(console->ConsoleLines[loop], 0, CON_CHARS_PER_LINE);
844 }
845
846 void Command_Up(ConsoleInformation *console) {
847 if(console->CommandScrollBack < console->TotalCommands - 1) {
848 /* move back a line in the command strings and copy the command to the current input string */
849 console->CommandScrollBack++;
850 memset(console->RCommand, 0, CON_CHARS_PER_LINE);
851 console->Offset = 0;
852 strcpy(console->LCommand, console->CommandLines[console->CommandScrollBack]);
853 console->CursorPos = strlen(console->CommandLines[console->CommandScrollBack]);
854 CON_UpdateConsole(console);
855 }
856 }
857
858 void Command_Down(ConsoleInformation *console) {
859 if(console->CommandScrollBack > -1) {
860 /* move forward a line in the command strings and copy the command to the current input string */
861 console->CommandScrollBack--;
862 memset(console->RCommand, 0, CON_CHARS_PER_LINE);
863 memset(console->LCommand, 0, CON_CHARS_PER_LINE);
864 console->Offset = 0;
865 if(console->CommandScrollBack > -1)
866 strcpy(console->LCommand, console->CommandLines[console->CommandScrollBack]);
867 console->CursorPos = strlen(console->LCommand);
868 CON_UpdateConsole(console);
869 }
870 }
871
0 #ifndef CON_console_H
1 #define CON_console_H
2
3
4 #define CON_CHARS_PER_LINE 128
5 #define CON_BLINK_RATE 500
6 #define CON_CHAR_BORDER 4
7 #define CON_DEFAULT_PROMPT "]"
8 #define CON_LINE_SCROLL 2
9 #define CON_SCROLL_INDICATOR "^"
10 #define CON_INS_CURSOR "_"
11 #define CON_OVR_CURSOR "|"
12
13
14 #ifdef __cplusplus
15 extern "C"
16 {
17 #endif
18
19 /* This is a struct for each consoles data */
20 typedef struct console_information_td
21 {
22 char **ConsoleLines; // List of all the past lines
23 char **CommandLines; // List of all the past commands
24 int TotalConsoleLines; // Total number of lines in the console
25 int ConsoleScrollBack; // How much the users scrolled back in the console
26 int TotalCommands; // Number of commands in the Back Commands
27 int FontNumber; // This is the number of the font for the console
28 int LineBuffer; // The number of visible lines in the console (autocalculated)
29 int VChars; // The number of visible characters in one console line (autocalculated)
30 int BackX, BackY; // Background images x and y coords
31 char* Prompt; // Prompt displayed in command line
32 char Command[CON_CHARS_PER_LINE]; // current command in command line = lcommand + rcommand
33 char RCommand[CON_CHARS_PER_LINE]; // left hand side of cursor
34 char LCommand[CON_CHARS_PER_LINE]; // right hand side of cursor
35 char VCommand[CON_CHARS_PER_LINE]; // current visible command line
36 int CursorPos; // Current cursor position in CurrentCommand
37 int Offset; // CommandOffset (first visible char of command) - if command is too long to fit into console
38 int InsMode; // Insert or Overwrite characters?
39 SDL_Surface *ConsoleSurface; // Surface of the console
40 SDL_Surface *OutputScreen; // This is the screen to draw the console to
41 SDL_Surface *BackgroundImage; // Background image for the console
42 SDL_Surface *InputBackground; // Dirty rectangle to draw over behind the users background
43 int DispX, DispY; // The top left x and y coords of the console on the display screen
44 unsigned char ConsoleAlpha; // The consoles alpha level
45 int CommandScrollBack; // How much the users scrolled back in the command lines
46 } ConsoleInformation;
47
48
49
50 void CON_Events(SDL_Event *event);
51 void CON_DrawConsole(ConsoleInformation *console);
52 ConsoleInformation *CON_Init(const char *FontName, SDL_Surface *DisplayScreen, int lines, SDL_Rect rect);
53 void CON_Destroy(ConsoleInformation *console);
54 void CON_Free(ConsoleInformation *console);
55 void CON_Out(ConsoleInformation *console, const char *str, ...);
56 void CON_Alpha(ConsoleInformation *console, unsigned char alpha);
57 int CON_Background(ConsoleInformation *console, const char *image, int x, int y);
58 void CON_Position(ConsoleInformation *console, int x, int y);
59 int CON_Resize(ConsoleInformation *console, SDL_Rect rect);
60 void CON_NewLineConsole(ConsoleInformation *console);
61 void CON_NewLineCommand(ConsoleInformation *console);
62 void CON_UpdateConsole(ConsoleInformation *console);
63 void CON_Topmost(ConsoleInformation *console);
64 void CON_SetPrompt(ConsoleInformation *console, char* newprompt);
65
66 void Cursor_Left(ConsoleInformation *console);
67 void Cursor_Right(ConsoleInformation *console);
68 void Cursor_Home(ConsoleInformation *console);
69 void Cursor_End(ConsoleInformation *console);
70 void Cursor_Del(ConsoleInformation *console);
71 void Cursor_BSpace(ConsoleInformation *console);
72 void Cursor_Add(ConsoleInformation *console, SDL_Event *event);
73
74 void Clear_Command(ConsoleInformation *console);
75 void Clear_History(ConsoleInformation *console);
76
77
78 //Console Commands
79
80 typedef struct CommandInfo_td
81 {
82 void (*CommandCallback)(ConsoleInformation *console, char *Parameters);
83 char *CommandWord;
84 struct CommandInfo_td *NextCommand;
85 } CommandInfo;
86
87
88 void CON_SendFullCommand(int sendOn);
89 void CON_CommandExecute(ConsoleInformation *console);
90 void CON_AddCommand(void (*CommandCallback)(ConsoleInformation *console, char *Parameters), const char *CommandWord);
91 void CON_TabCompletion(ConsoleInformation *console);
92 void CON_ListCommands(ConsoleInformation *console);
93 void CON_DestroyCommands();
94
95
96 #ifdef __cplusplus
97 };
98 #endif
99
100 #endif
101
102
0 /* CON_consolecommands.c
1 * Written By: Garrett Banuk <mongoose@mongeese.org>
2 * This is free, just be sure to give me credit when using it
3 * in any of your programs.
4 */
5
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include "SDL.h"
11 #include "CON_console.h"
12 #include "internal.h"
13
14
15 /* Linked list of all the commands. */
16 static CommandInfo *Commands = NULL;
17 static int SendCommand = 0;
18
19
20 /* executes the command passed in from the string */
21 void CON_CommandExecute(ConsoleInformation *console)
22 {
23 char Command[CON_CHARS_PER_LINE];
24 char *BackStrings = console->Command;
25 CommandInfo *CurrentCommand = Commands;
26
27 /* Get the command out of the string */
28 if(EOF == sscanf(BackStrings, "%s", Command))
29 return;
30
31 CurrentCommand = Commands;
32 while(CurrentCommand) {
33 if(0 == strcmp(Command, CurrentCommand->CommandWord)) {
34 if (SendCommand)
35 CurrentCommand->CommandCallback(console, BackStrings);
36 else
37 CurrentCommand->CommandCallback(console, BackStrings+strlen(Command)+1);
38 return;
39 }
40 CurrentCommand = CurrentCommand->NextCommand;
41 }
42 CON_Out(console, "Unknown Command \"%s\"", Command);
43 }
44
45 /* Use this to add commands.
46 * Pass in a pointer to a funtion that will take a string which contains the
47 * arguments passed to the command. Second parameter is the command to execute
48 * on.
49 */
50 void CON_AddCommand(void(*CommandCallback)(ConsoleInformation *console, char *Parameters), const char *CommandWord)
51 {
52 CommandInfo **CurrentCommand = &Commands;
53
54
55 while(*CurrentCommand)
56 CurrentCommand = &((*CurrentCommand)->NextCommand);
57
58 /* Add a command to the list */
59 *CurrentCommand = (CommandInfo*)malloc(sizeof(CommandInfo));
60 (*CurrentCommand)->CommandCallback = CommandCallback;
61 (*CurrentCommand)->CommandWord = (char*)malloc(strlen(CommandWord)+1);
62 strcpy((*CurrentCommand)->CommandWord, CommandWord);
63 (*CurrentCommand)->NextCommand = NULL;
64 }
65
66 /* tab completes commands
67 * It takes a string to complete and a pointer to the strings length. The strings
68 * length will be modified if the command is completed. */
69 void CON_TabCompletion(ConsoleInformation *console)
70 {
71 int Matches = 0;
72 int *location = &console->CursorPos;
73 char *CommandLine = console->LCommand;
74 char temp[CON_CHARS_PER_LINE];
75 CommandInfo *CurrentCommand;
76
77 // Don't try to complete if nothing is entered
78 if(*location == 0)
79 return;
80
81
82 /* Find all the commands that match */
83 CurrentCommand = Commands;
84 while(CurrentCommand)
85 {
86 if(0 == strncmp(CommandLine, CurrentCommand->CommandWord, strlen(CommandLine)))
87 Matches++;
88 CurrentCommand = CurrentCommand->NextCommand;
89 }
90
91 /* if we got one match, find it again and execute it */
92 if(Matches == 1)
93 {
94 CurrentCommand = Commands;
95 while(CurrentCommand)
96 {
97 if(0 == strncmp(CommandLine, CurrentCommand->CommandWord, strlen(CommandLine)))
98 {
99 strcpy(CommandLine, CurrentCommand->CommandWord);
100 CommandLine[strlen(CurrentCommand->CommandWord)] = ' ';
101 *location = strlen(CurrentCommand->CommandWord)+1;
102 CON_UpdateConsole(console);
103 break;
104 }
105 CurrentCommand = CurrentCommand->NextCommand;
106 }
107 }
108 else if(Matches > 1)/* multiple matches so print them out to the user */
109 {
110 CON_NewLineConsole(console);
111 CurrentCommand = Commands;
112 while(CurrentCommand)
113 {
114 if(0 == strncmp(CommandLine, CurrentCommand->CommandWord, strlen(CommandLine))) {
115 strcpy(temp, " ");
116 strcpy(&temp[5], CurrentCommand->CommandWord);
117 CON_Out(console, temp);
118 }
119 CurrentCommand = CurrentCommand->NextCommand;
120 }
121 }
122 else if(Matches == 0) {
123 // Thats not very interesting..
124 //CON_Out(console, "No match");
125 }
126 }
127
128
129 /* Lists all the commands to be used in the console */
130 void CON_ListCommands(ConsoleInformation *console)
131 {
132 CommandInfo *CurrentCommand = Commands;
133
134 CON_Out(console, " ");
135 while(CurrentCommand)
136 {
137 CON_Out(console, " %s", CurrentCommand->CommandWord);
138 CurrentCommand = CurrentCommand->NextCommand;
139 }
140
141 }
142
143 /* sends the command word used and the parameters back */
144 void CON_SendFullCommand(int sendOn)
145 {
146 SendCommand = sendOn;
147 }
148
149 /* This frees all the memory used by the commands */
150 void CON_DestroyCommands()
151 {
152 CommandInfo *CurrentCommand = Commands;
153 CommandInfo *temp;
154
155 while(CurrentCommand)
156 {
157 temp = CurrentCommand;
158 CurrentCommand = CurrentCommand->NextCommand;
159
160 free(temp->CommandWord);
161 free(temp);
162 }
163 Commands = NULL;
164 }
165
166
0 /* DT_drawtext.c
1 * Written By: Garrett Banuk <mongoose@mongeese.org>
2 * This is free, just be sure to give me credit when using it
3 * in any of your programs.
4 */
5
6 #include <string.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "SDL.h"
10 #include "SDL_image.h"
11 #include "DT_drawtext.h"
12 #include "internal.h"
13
14
15 static BitFont *BitFonts = NULL; /* Linked list of fonts */
16
17
18 /* sets the transparency value for the font in question. assumes that
19 * we're in an OpenGL context. */
20 void DT_SetFontAlphaGL(int FontNumber, int a)
21 {
22 unsigned char val;
23 BitFont *CurrentFont;
24 unsigned char r_targ, g_targ, b_targ;
25 int i, imax;
26 unsigned char *pix;
27
28 /* get pointer to font */
29 CurrentFont = DT_FontPointer(FontNumber);
30 if(CurrentFont == NULL)
31 {
32 PRINT_ERROR("Setting font alpha for non-existent font!\n");
33 return;
34 }
35 if(CurrentFont->FontSurface->format->BytesPerPixel == 2)
36 {
37 PRINT_ERROR("16-bit SDL surfaces do not support alpha-blending under OpenGL\n");
38 return;
39 }
40 if(a < SDL_ALPHA_TRANSPARENT)
41 val = SDL_ALPHA_TRANSPARENT;
42 else if(a > SDL_ALPHA_OPAQUE)
43 val = SDL_ALPHA_OPAQUE;
44 else
45 val = a;
46
47 /* iterate over all pixels in the font surface. For each
48 * pixel that is (255,0,255), set its alpha channel
49 * appropriately. */
50 imax = CurrentFont->FontSurface->h * (CurrentFont->FontSurface->w << 2);
51 pix = (unsigned char *)(CurrentFont->FontSurface->pixels);
52 r_targ = 255; /*pix[0]; */
53 g_targ = 0; /*pix[1]; */
54 b_targ = 255; /*pix[2]; */
55 for(i = 3; i < imax; i += 4)
56 if(pix[i - 3] == r_targ && pix[i - 2] == g_targ && pix[i - 1] == b_targ)
57 pix[i] = val;
58 /* also make sure that alpha blending is disabled for the font
59 surface. */
60 SDL_SetAlpha(CurrentFont->FontSurface, 0, SDL_ALPHA_OPAQUE);
61 }
62
63 /* Loads the font into a new struct
64 * returns -1 as an error else it returns the number
65 * of the font for the user to use
66 */
67 int DT_LoadFont(const char *BitmapName, int flags)
68 {
69 int FontNumber = 0;
70 BitFont **CurrentFont = &BitFonts;
71 SDL_Surface *Temp;
72
73
74 while(*CurrentFont)
75 {
76 CurrentFont = &((*CurrentFont)->NextFont);
77 FontNumber++;
78 }
79
80 /* load the font bitmap */
81 if(NULL == (Temp = IMG_Load(BitmapName)))
82 {
83 PRINT_ERROR("Cannot load file ");
84 printf("%s\n", BitmapName);
85 return -1;
86 }
87
88 /* Add a font to the list */
89 *CurrentFont = (BitFont *) malloc(sizeof(BitFont));
90
91 (*CurrentFont)->FontSurface = SDL_DisplayFormat(Temp);
92 SDL_FreeSurface(Temp);
93
94 (*CurrentFont)->CharWidth = (*CurrentFont)->FontSurface->w / 256;
95 (*CurrentFont)->CharHeight = (*CurrentFont)->FontSurface->h;
96 (*CurrentFont)->FontNumber = FontNumber;
97 (*CurrentFont)->NextFont = NULL;
98
99
100 /* Set font as transparent if the flag is set. The assumption we'll go on
101 * is that the first pixel of the font image will be the color we should treat
102 * as transparent.
103 */
104 if(flags & TRANS_FONT)
105 {
106 if(SDL_GetVideoSurface()->flags & SDL_OPENGLBLIT)
107 DT_SetFontAlphaGL(FontNumber, SDL_ALPHA_TRANSPARENT);
108 else
109 SDL_SetColorKey((*CurrentFont)->FontSurface, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB((*CurrentFont)->FontSurface->format, 255, 0, 255));
110 }
111 else if(SDL_GetVideoSurface()->flags & SDL_OPENGLBLIT)
112 DT_SetFontAlphaGL(FontNumber, SDL_ALPHA_OPAQUE);
113
114 return FontNumber;
115 }
116
117 /* Takes the font type, coords, and text to draw to the surface*/
118 void DT_DrawText(const char *string, SDL_Surface *surface, int FontType, int x, int y)
119 {
120 int loop;
121 int characters;
122 int current;
123 SDL_Rect SourceRect, DestRect;
124 BitFont *CurrentFont;
125
126 CurrentFont = DT_FontPointer(FontType);
127
128 /* see how many characters can fit on the screen */
129 if(x > surface->w || y > surface->h)
130 return;
131
132 if(strlen(string) < (surface->w - x) / CurrentFont->CharWidth)
133 characters = strlen(string);
134 else
135 characters = (surface->w - x) / CurrentFont->CharWidth;
136
137 DestRect.x = x;
138 DestRect.y = y;
139 DestRect.w = CurrentFont->CharWidth;
140 DestRect.h = CurrentFont->CharHeight;
141
142 SourceRect.y = 0;
143 SourceRect.w = CurrentFont->CharWidth;
144 SourceRect.h = CurrentFont->CharHeight;
145
146 /* Now draw it */
147 for(loop = 0; loop < characters; loop++)
148 {
149 current = string[loop];
150 if (current<0 || current > 255)
151 current = 0;
152 //SourceRect.x = string[loop] * CurrentFont->CharWidth;
153 SourceRect.x = current * CurrentFont->CharWidth;
154 SDL_BlitSurface(CurrentFont->FontSurface, &SourceRect, surface, &DestRect);
155 DestRect.x += CurrentFont->CharWidth;
156 }
157 /* if we're in OpenGL-mode, we need to manually update after blitting. */
158 if(surface->flags & SDL_OPENGLBLIT)
159 {
160 DestRect.x = x;
161 DestRect.w = characters * CurrentFont->CharWidth;
162 SDL_UpdateRects(surface, 1, &DestRect);
163 }
164 }
165
166
167 /* Returns the height of the font numbers character
168 * returns 0 if the fontnumber was invalid */
169 int DT_FontHeight(int FontNumber)
170 {
171 BitFont *CurrentFont;
172
173 CurrentFont = DT_FontPointer(FontNumber);
174 if(CurrentFont)
175 return CurrentFont->CharHeight;
176 else
177 return 0;
178 }
179
180 /* Returns the width of the font numbers charcter */
181 int DT_FontWidth(int FontNumber)
182 {
183 BitFont *CurrentFont;
184
185 CurrentFont = DT_FontPointer(FontNumber);
186 if(CurrentFont)
187 return CurrentFont->CharWidth;
188 else
189 return 0;
190 }
191
192 /* Returns a pointer to the font struct of the number
193 * returns NULL if theres an error
194 */
195 BitFont *DT_FontPointer(int FontNumber)
196 {
197 BitFont *CurrentFont = BitFonts;
198 BitFont *temp;
199
200 while(CurrentFont)
201 if(CurrentFont->FontNumber == FontNumber)
202 return CurrentFont;
203 else
204 {
205 temp = CurrentFont;
206 CurrentFont = CurrentFont->NextFont;
207 }
208
209 return NULL;
210
211 }
212
213 /* removes all the fonts currently loaded */
214 void DT_DestroyDrawText()
215 {
216 BitFont *CurrentFont = BitFonts;
217 BitFont *temp;
218
219 while(CurrentFont)
220 {
221 temp = CurrentFont;
222 CurrentFont = CurrentFont->NextFont;
223
224 SDL_FreeSurface(temp->FontSurface);
225 free(temp);
226 }
227
228 BitFonts = NULL;
229 }
230
231
0 #ifndef Drawtext_h
1 #define Drawtext_h
2
3
4 #define TRANS_FONT 1
5
6
7 #ifdef __cplusplus
8 extern "C" {
9 #endif
10
11 typedef struct BitFont_td
12 {
13 SDL_Surface *FontSurface;
14 int CharWidth;
15 int CharHeight;
16 int FontNumber;
17 struct BitFont_td *NextFont;
18 } BitFont;
19
20
21 void DT_DrawText(const char *string, SDL_Surface *surface, int FontType, int x, int y );
22 int DT_LoadFont(const char *BitmapName, int flags );
23 int DT_FontHeight( int FontNumber );
24 int DT_FontWidth( int FontNumber );
25 BitFont* DT_FontPointer(int FontNumber );
26 void DT_DestroyDrawText();
27
28
29 #ifdef __cplusplus
30 };
31 #endif
32
33 #endif
34
35
36
0 #Makefile for the SDL_Console library
1
2 INCLUDE = `sdl-config --cflags` -lSDL_image
3 CC = gcc
4 C = CON_console.c CON_consolecommands.c DT_drawtext.c internal.c
5 OBJS = CON_console.o CON_consolecommands.o DT_drawtext.o internal.o
6 CFLAGS = -O2
7
8 prefix = $(DEST)/usr
9 libdir = $(prefix)/lib
10 incdir = $(prefix)/include/SDL
11
12 all: libSDL_console.so libSDL_console.a
13
14 libSDL_console.so:
15 $(CC) -c $(C) -fPIC $(INCLUDE)
16 $(CC) -fPIC -shared $(OBJS) -o libSDL_console.so $(INCLUDE)
17
18 libSDL_console.a: $(OBJS)
19 ar cru libSDL_console.a $(OBJS)
20
21 install:
22 install -d $(libdir)
23 install -d $(incdir)
24 install libSDL_console.so $(libdir)
25 install libSDL_console.a $(libdir)
26 install CON_console.h $(incdir)
27 install DT_drawtext.h $(incdir)
28
29 uninstall:
30 rm -f $(libdir)libSDL_console.so
31 rm -f $(incdir)/CON_console.h
32 rm -f $(incdir)/DT_drawtext.h
33
34 clean:
35 rm -f $(OBJ) libSDL_console.so libSDL_console.a core $(OBJS)
36
0 <html>
1 <head>
2 <title>SDL Console</title>
3 </HEAD>
4
5 <body link="#0000FF" vlink="#551A8B" alink="#FF0000">
6
7 <center><h1>SDL Console</h1></center>
8
9 <br><br><b>Author:</b> <a href="mailto:talanthyr@tuxfamily.org">Boris Lesner</a>
10 <br><b>Original project by:</b> <a href="mailto:mongoose@mongeese.org">Garrett Banuk</a><br><br>
11
12 <strong>Description:</strong><br>
13 This is a console that can be added to any SDL application. It
14 is similar to Quake and other game consoles but with lots of added
15 features. A console is meant to be a very simple way of interacting
16 with a program and executing commands. Commands are linked to the
17 console with callback functions so that when a command is typed
18 in, a specific function is executed automatically.
19 <br>SDL_Console is released under GNU/LGPL licence ( see <a href="http://www.gnu.org/copyleft/lesser.html">www.gnu.org</a> for more information )
20
21 <br><br>
22 <strong>Depends:</strong><br>
23 SDL_console depends of the following libs :<br>
24 <b>SDL</b> : <a href="http://www.libsdl.org">www.libsdl.org</a>
25 <b>SDL_image</b> : <a href="http://www.libsdl.org/projects/SDL_image">http://www.libsdl.org/projects/SDL_image</a>
26
27 <br><br><b>September 19, 2002</b>
28 SDL_console 1.3 is released! Wacha Clemens again couldn't stop adding stuff to the code.<br>
29 I has too many features and bugfixes to mention them here. For a complete list see below.<br>
30 He has completely rewritten the command line and added lots of useful control keys.
31
32 <br><br><b>September 13, 2002</b>
33 SDL_console 1.2 is released thanks to Wacha Clemens who added a prompt, autoscrolling commandline, and buxfixes.<br>
34 I also added CON_Free() which equals to CON_Destroy but without destroying text support of DT ( thanks to Paul Wighton ), CON_Destroy still in the lib for compatibility.
35
36 <br><br><b>September 03, 2002</b>
37 Garrett give me the SDL_console project and I hope I could add nice changes to the lib !
38 <br>But's it's already stable and I think that only a few things would be added.<br>For now I added a debian package of SDL_Console, the SDL_image support for PNG, JPG, ... images formats, and a shared library of the lib.
39 <br>SDL_console is now version 1.1.
40 <br> Boris Lesner.
41
42 <br><br>
43 <b>July 12, 2002</b> <font color="red" size="+1"><b>SDL_Console needs a new author!</b></font> I no longer have the time to work on SDL_Console with my new job and other interests and due to the popularity of SDL_Console, I do not want to let the project stagnate. I'm going to give the project away to someone else to maintain and improve as they see fit. The new author will have full control of the project and may do with it as they please. If you are interested in taking over the project, please <a href="mailto:mongoose@mongeese.org">email</a> me. Give me some information about your computer science skills, projects you've worked on, etc. After/if I get a sufficient response from interested people, I will decide who will take over the project. Thanks for all the support from everyone. I hope this project is still useful in the future.
44
45 <br><br>
46 <b>Nov 14, 2001</b> <a href="mailto:cort@andrew.cmu.edu">Cort Stratton</a> added a new MSVC project for the console with the new source.
47
48 <br><br>
49 <b>Oct 8, 2001</b> Finally an update to SDL_console! SDL_console has now reached version 1.0. I figured it's about time since there have not been any bug fixes for a while so the code is pretty solid. There are also lots of new additions to the code and a decent Makefile system now. If anyone wants to write an autoconf system though, be my guest.
50 <ul>
51 <li>Backward compatibilty has been completely broken. See the API below.</li>
52 <li>Multiple independant consoles can be displayed on the screen. Checkout the <a href="screen3.jpg">screenshot</a>.</li>
53 <li>Better Makefile system. Should be a little easier to work with now.</li>
54 <li>Fixed a few performance issues.</li>
55 <li>Cleaned up the code. Cutting and pasting everyones different coding styles into the source was getting messy.</li>
56 </ul>
57
58 <br><br>
59 <b>June 12, 2001</b> <a href="mailto:slim@maya.com">Seung Chan Lim</a> Has donated a version of SDL_Console with the demo in MSVC project format. You can download it below.
60
61 <br><br>
62 <b>May 15, 2001</b> Now the console <i>really</i> works with OpenGL. =) Thanks to <a href="mailto:cort@andrew.cmu.edu">Cort Stratton</a> for fixing the OpenGL support. The console example source now demonstrates it's use with OpenGL. There is also the non-OpenGL sample source included in the archive. As usual there were a few cosmetic modifications and bug fixes also.
63
64
65 <br><br>
66 <b>Apr 29, 2001</b> I added a blinking cursor showing the current editing position due to popular demand. Ugh I didn't realize how ugly this code was. =) It's efficient, just not very neat.
67 <ul>
68 <li>Added a blinking cursor showing the current text position.</li>
69 <li>Reorganized some of the code to be more readable.</li>
70 </ul>
71
72
73 <b>Feb 20, 2001</b> Thanks to <a href="mailto:pcruz@qwest.net">Patricia Cruz</a> for adding an OpenGL fix to the Console source.
74 <ul>
75 <li>Console now works within an OpenGL program and can be blitted to OpenGL surfaces.</li>
76 </ul>
77
78 <b>Nov 18, 2000</b> Lots of new changes here, mainly thanks to Lee Thomason for submitting some of them and motivating me to work on this again.
79 <ul>
80 <li>Naming conventions have been changed. Console commands now start with the CON_ prefix so as not to be confused with SDL_. Also the text drawing routines now start with DT_ so that they are distinguished as being seperate from the console.</li>
81 <li>Console is no longer `attached' to the top of the screen, it is now a box that can be located anywhere. CON_Position(int x, int y)</li>
82 <li>The console can be resized without reinitializing. CON_Resize(SDL_Rect rect)</li>
83 <li>Tab completion lists all the matching commands rather than just completing with the first command it partially matches with. (Ya I know, this ones been overdue.)</li>
84 <li>An option can be set to send back the command with the parameters from the user rather than just the parameters. So now multiple commands can be sent to one function and be distinguished from each other. CON_SendFullCommand(int sendOn)</li>
85 <li>New command CON_Destroy() now shuts down and frees the console from the program. DT_DestroyDrawText() does the same thing for the text drawing routines.</li>
86 <li>CON_SetConsoleBorder() has been removed. This is because of the new free moving console. Setting a border around the edges is much more complicated so I won't bother implementing this unless people ask for it.</li>
87 <li>All of the help resources are going onto the webpage now rather than in the README file.</li>
88 </ul>
89
90 <b>April 16, 1999</b>
91 <ul>
92 <li>Scroll back buffer amount can be specified at init.</li>
93 <li>PageUP PageDOWN scrolling through the buffer.</li>
94 <li>Printing to the console is done with printf() similiar arguments.</li>
95 <li>Tab completion of commands.</li>
96 <li>Arbitrary number of commands can be added.</li>
97 <li>Arbitrary number of arguments to each command from the input.</li>
98 <li>Alpha blending onto the destination surface.(optional for speed)</li>
99 <li>Border/Background image.(optional for speed)</li>
100 <li>Any bitmap font can be used.</li>
101 </ul>
102
103 Also included is text and font handling routines for bitmap fonts.
104 Bitmap fonts can be loaded up and text can be outputted to the surfaces
105 using the different fonts. These bitmap font routines can be used seperately
106 without the console. The text drawing routines are in the files DT_*
107
108 <br><br><strong>Source:</strong><br>
109 <a href="SDL_console-1.2.tar.gz">[Console and Example (SDL_console-1.2.tar.gz)]</a><br>
110 <a href="SDL_console-1.2.zip">[Console and Example for MSVC (SDL_console-1.2.zip)]</a><br>
111 <br><br>Additions and modifications are welcome.<br><a href="mailto:talanthyr@tuxfamily.org">Email</a> me if you have suggestions for other things to be added or fixes.
112
113 <br><br><strong>ScreenShots:</strong><br>
114 <a href="screen1.jpg">Small console</a>
115 <br><a href="screen2.jpg">Stretched to half the screen</a>
116 <br><a href="screen3.jpg">Multiple consoles on the same screen</a>
117
118 <br>
119 <br><b>Keyboard controls</b>
120 <br><br>
121 <table>
122 <tr>
123 <td>Up</td>
124 <td>move command history up</td>
125 </tr>
126 <tr>
127 <td>Down</td>
128 <td>move command history down</td>
129 </tr>
130 <tr>
131 <td>Left</td>
132 <td>move cursor left</td>
133 </tr>
134 <tr>
135 <td>Right</td>
136 <td>move cursor right</td>
137 </tr>
138 <tr>
139 <td>Ins</td>
140 <td>toggle overwrite mode (you can set the two different cursor in CON_console.h)</td>
141 </tr>
142 <tr>
143 <td>Del</td>
144 <td>delete character above cursor</td>
145 </tr>
146 <tr>
147 <td>Backspace</td>
148 <td>delete character left of cursor</td>
149 </td>
150 <tr>
151 <td>Home</td>
152 <td>move cursor to begin of command</td>
153 </tr>
154 <tr>
155 <td>End</td>
156 <td>move cursor to end of command</td>
157 </tr>
158 <tr>
159 <td>Ctrl-A</td>
160 <td>same as Home</td>
161 </tr>
162 <tr>
163 <td>Ctrl-E</td>
164 <td>same as End</td>
165 </tr>
166 <tr>
167 <td>Ctrl-C</td>
168 <td>clear commandline</td>
169 </tr>
170 <tr>
171 <td>Page-Up</td>
172 <td>move history up</td>
173 </tr>
174 <tr>
175 <td>Page-Down</td>
176 <td>move history down</td>
177 </tr>
178 <tr>
179 <td>Shift-Home</td>
180 <td>move to top of history</td>
181 </tr>
182 <tr>
183 <td>Shift-End</td>
184 <td>move to end of history</td>
185 </tr>
186 <tr>
187 <td>Ctrl-L</td>
188 <td>clear history</td>
189 </tr>
190 </table>
191
192 <br><br><strong>API:</strong><br>
193
194 Heres an overview of the CONSOLE API.
195
196 <br>
197 <br><b>#include "CON_Console.h"</b>
198
199 <br><br>
200 Most of these functions take a pointer to a ConsoleInformation struct. This tells what console the function should proccess on. A new ConsoleInformation pointer is created with Con_Init().
201
202 <br><br><b>ConsoleInformation *CON_Init( char *FontName, SDL_Surface *DisplayScreen, int lines, SDL_Rect rect )</b>
203 <br>Takes in a string of the path to the bitmap fontname, the surface the console will be displayed on, the number of lines in the back buffer of the console and an SDL_Rect with the x,y location and width and height. It returns a pointer to a ConsoleInformation struct, or NULL on error.
204
205 <br><br><b>void CON_Events( SDL_Event *event )</b>
206 <br>Send SDL events to this to be processed when the console is down. Be sure to set SDL_EnableUNICODE(1); for SDL before the commands are sent to the console so the console can interpet the commands. The events are sent to the console registered with CON_Topmost();
207
208 <br><br><b>void CON_DrawConsole( ConsoleInformation *console )</b>
209 <br>Draws the console on the screen.
210
211 <br><br><b>void CON_Out( ConsoleInformation *console, char *str, ... )</b>
212 <br>Displays strings to the console, works just like printf()
213
214 <br><br><b>void CON_CommandExecute( ConsoleInformation *console, char *BackStrings )</b>
215 <br>Executes a command string passed to it. Usually only used internally by the console API.
216
217 <br><br><b>void CON_AddCommand( void (*CommandCallback)(ConsoleInformation *console, char *Parameters), char *CommandWord )</b>
218 <br>The first parameter of this is a pointer to a function that takes a ConsoleInformation pointer and a string pointer as a parameter. The ConsoleInformation pointer is the console the command was typed in, the string is the arguments passed to the command in the console. The second parameter of AddCommand is the string of the command (no space) the user will type into the console to call this function.
219
220 <br><br><b>void CON_ListCommands( ConsoleInformation *console )</b>
221 <br>Lists the commands in the console.
222
223 <br><br><b>void CON_SendFullCommand( int sendOn )</b>
224 <br>This sets a flag so that the command and the arguments typed in by the user are all sent to the callback function. This is helpful in that one callback function can be used for multiple different commands typed in by the user and easily distinguished.
225
226 <br><br><b>int CON_Background( ConsoleInformation *console, char *image, int x, int y )</b>
227 <br>Loads the file from image to the location (x,y) on the background. If this function is passed NULL for image the background is unloaded.
228
229 <br><br><b>void CON_Alpha( ConsoleInformation *console, unsigned char alpha )</b>
230 <br>Alpha blends the console into the background, value range is 1-200.
231 If the alpha value passed is 0 alpha blending is turned off.
232
233 <br><br><b>void CON_Destroy( ConsoleInformation *console )</b>
234 <br>This shuts down and frees the console resources.
235
236 <br><br><b>void CON_Free( ConsoleInformation *console )</b>
237 <br>This shuts down and frees the console resources but not DrawText ressources.
238
239 <br><br><b>void CON_SetPrompt(ConsoleInformation *console, char *string)</b>
240 <br>This sets the prompt of the console <i>console</i> to <i>string</i>
241
242 <br><br><b>void CON_Position( ConsoleInformation *console, int x, int y )</b>
243 <br>This positions the console in the new x,y location.
244
245 <br><br><b>int CON_Resize( ConsoleInformation *console, SDL_Rect rect )</b>
246 <br>This takes an SDL_Rect to resize and move the console window. Use CON_Position() if you are just moving the console though as the resizing function has to reinitialize resources and so takes longer.
247
248 <br><br><b>Special Keys</b>
249 <br>Page_UP Page_DOWN scroll around the back buffer of the console TAB tab completes commands END goes back to the bottom of the console
250
251 <br><br><br><br>Heres an overview of the DRAW TEXT API.
252
253 <br><br><b>#include "SDL_DrawText.h"</b>
254
255 <br><br><b>int DT_LoadFont( char *BitmapName, int flags )</b>
256 <br>Loads a font from the BitmapName file and returns the
257 number of the font. returns -1 as an error. Pass TRANS_FONT
258 to the flags if the font is transparent. Transparent color is
259 RGB(255,0,255)
260
261 <br><br><b>void DT_DrawText( char *string, SDL_Surface *surface, int FontType, int x, int y )</b>
262 <br>Draws text to the screen. First parameter is the text to
263 draw, second is the surface to draw too, third is the font
264 type to draw, last two are the x,y screen location.
265
266 <br><br><b>int DT_FontHeight( int FontNumber )</b>
267 <br>returns the font character height.
268
269 <br><br><b>int DT_FontWidth( int FontNumber )</b>
270 <br>returns the font character width.
271
272 <br><br><b>void DT_DestroyDrawText( )</b>
273 <br>Shuts down and frees all the resources used by the text drawing routines.
274
275 <br><br><b>Demo info:</b>
276 <br>In this demo the keys CTRL+[1,2,3] display the consoles 1, 2 or 3 to the screen. To select which console you want to type to press ALT+[1,2,3]. ALT+4 directs input back to the program.
277
278 <br><br><a href="http://www.tuxfamily.org">TUXFAMILY</a>
279
280 </body>
281 </html>
0 SDL Console
1 A console and text output routine written for SDL.
2
3 Garrett Banuk
4 (mongoose@mongeese.org)
5 Boris Lesner
6 (talanthyr@tuxfamily.org)
7 Clemens Wacha
8 (reflex-2000@gmx.net)
9
10 http://sdlconsole.tuxfamily.org/
11
12 Please see the index.html file for info.
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 /* This is an example of the console code for SDL
1 * Garrett Banuk (mongoose@mongeese.org)
2 */
3
4 #ifdef GL_DEMO
5 #include <GL/glut.h>
6 #endif /* GL_DEMO */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include "SDL.h"
11 #include "CON_console.h"
12 #include "DT_drawtext.h"
13 #include "ConsoleExample.h"
14
15
16 int MainProgram = 1;
17 int TextDemo = 0;
18 int LargeFont;
19
20
21
22 #define CONSOLE_N 3
23 ConsoleInformation *Consoles[CONSOLE_N];/* Pointers to all the consoles */
24 int ConsoleDisplay[CONSOLE_N]; /* Bools telling if the console is displayed */
25
26
27 int main(int argc, char **argv)
28 {
29 SDL_Surface *Screen;
30 int ticks = 0, oldticks = 0;
31 int i;
32 char framerate[30];
33 SDL_Rect Con_rect;
34
35
36
37 /* init the graphics */
38 if(Init(&Screen, argc, argv))
39 return 1;
40
41
42 /* Init the consoles */
43 Con_rect.x = Con_rect.y = 0;
44 Con_rect.w = Con_rect.h = 300;
45 if((Consoles[0] = CON_Init("ConsoleFont.png", Screen, 100, Con_rect)) == NULL)
46 return 1;
47
48 Con_rect.x = 350;
49 Con_rect.y = 20;
50 Con_rect.w = Con_rect.h = 200;
51 if((Consoles[1] = CON_Init("ConsoleFont.png", Screen, 100, Con_rect)) == NULL)
52 return 1;
53
54 Con_rect.x = 340;
55 Con_rect.y = 280;
56 Con_rect.w = 300;
57 Con_rect.h = 200;
58 if((Consoles[2] = CON_Init("ConsoleFont.png", Screen, 100, Con_rect)) == NULL)
59 return 1;
60
61
62 /* Add some commands to the console */
63 CON_AddCommand(&KillProgram, "quit");
64 CON_AddCommand(&Echo, "echo");
65 CON_AddCommand(&DrawTextDemo, "drawtextdemo");
66 CON_AddCommand(&AlphaChange, "alpha");
67 CON_AddCommand(&AddBackground, "background");
68 CON_AddCommand(&Move, "move");
69 CON_AddCommand(&Resize, "resize");
70 CON_AddCommand(&ListCommands, "listcommands");
71 CON_AddCommand(&SetPrompt, "prompt");
72
73 CON_ListCommands(Consoles[0]);
74
75 /* Heres another font for the text demo */
76 LargeFont = DT_LoadFont("LargeFont.png", 0);
77
78 /* Main execution loop */
79 while(MainProgram)
80 {
81 ProcessEvents();
82
83 /* wipe the screen clean with a blue fill and draw the console if its down */
84 #ifdef GL_DEMO
85 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
86 glMatrixMode(GL_MODELVIEW);
87 glLoadIdentity();
88 glTranslatef(0.0, 0.0, -5.0);
89 glutSolidTeapot(2.0);
90 glFlush();
91 #else
92 SDL_FillRect(Screen, NULL, 255);
93 #endif /* GL_DEMO */
94
95 if(TextDemo)
96 RandText(Screen);
97
98 for(i=0; i<CONSOLE_N; i++)
99 if(ConsoleDisplay[i]) CON_DrawConsole(Consoles[i]);
100
101 /* print the framerate */
102 oldticks = ticks;
103 ticks = SDL_GetTicks();
104 sprintf(framerate, "%.2f FPS", 1000.0 / (ticks - oldticks));
105 DT_DrawText(framerate, Screen, 1, 1, Screen->h - 40);
106
107 #ifdef GL_DEMO
108 SDL_GL_SwapBuffers();
109 #else
110 SDL_Flip(Screen);
111 #endif /* GL_DEMO */
112 }
113
114 for(i=0; i<CONSOLE_N; i++)
115 CON_Destroy(Consoles[i]);
116
117 return 0;
118 }
119
120 #ifdef GL_DEMO
121 /* SETUP_OPENGL -- initializes assorted OpenGL parameters */
122 void setup_opengl(int width, int height)
123 {
124 float ratio = (float)width / (float)height;
125 /* lighting init */
126 GLfloat mat_diffuse[] = { 0.9, 0.9, 0.0, 1.0 };
127 GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
128 GLfloat mat_shininess[] = { 50.0 };
129 GLfloat light_position[] = { 1.0, 0.0, 5.0, 0.0 };
130 GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
131
132 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
133 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
134 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
135 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
136 glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
137 glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
138
139 glEnable(GL_LIGHTING);
140 glEnable(GL_LIGHT0);
141 glEnable(GL_DEPTH_TEST);
142
143 /* Set the clear color. */
144 glClearColor(0.0, 0.0, 1.0, 1.0);
145
146 /* Setup our viewport. */
147 glViewport(0, 0, width, height);
148
149 /* Change to the projection matrix and set our viewing volume. */
150 glMatrixMode(GL_PROJECTION);
151 glLoadIdentity();
152 gluPerspective(60.0, ratio, 1.0, 1024.0);
153 }
154 #endif /* GL_DEMO */
155
156 /* Initialise the graphics */
157 int Init(SDL_Surface **Screen, int argc, char **argv)
158 {
159 #ifdef GL_DEMO
160 int SetVideoFlags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_OPENGLBLIT;
161 int width = 640, height = 480, depth = 24;
162 #else
163 int SetVideoFlags = SDL_HWSURFACE | SDL_DOUBLEBUF;
164 int width = 640, height = 480, depth = 16;
165 #endif /* GL_DEMO */
166 int loop;
167
168 for(loop = 1; loop < argc; loop++)
169 {
170 if(strcmp(argv[loop], "-fullscreen") == 0)
171 SetVideoFlags |= SDL_FULLSCREEN;
172 else if(strcmp(argv[loop], "-width") == 0)
173 width = atoi(argv[++loop]);
174 else if(strcmp(argv[loop], "-height") == 0)
175 height = atoi(argv[++loop]);
176 else if(strcmp(argv[loop], "-bpp") == 0)
177 depth = atoi(argv[++loop]);
178 else if(strcmp(argv[loop], "-sw") == 0)
179 SetVideoFlags |= SDL_SWSURFACE;
180
181 }
182
183 if(SDL_Init(SDL_INIT_VIDEO) < 0)
184 {
185 fprintf(stderr, "*Error* Couldn't initialize SDL: %s\n", SDL_GetError());
186 return 1;
187 }
188
189 #ifdef GL_DEMO
190 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
191 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
192 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
193 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
194 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
195 #endif /* GL_DEMO */
196
197 if((*Screen = SDL_SetVideoMode(width, height, depth, SetVideoFlags)) == NULL)
198 {
199 fprintf(stderr, "*Error* Couldn't set %dx%dx%d video mode: %s\n", width, height, depth, SDL_GetError());
200 SDL_Quit();
201 return 1;
202 }
203
204 #ifdef GL_DEMO
205 setup_opengl(width, height);
206 #endif /* GL_DEMO */
207
208 atexit(SDL_Quit);
209 return 0;
210 }
211
212
213 /* Processes all the incoming events
214 */
215 void ProcessEvents()
216 {
217 SDL_Event event;
218 static int console_events = 0; /* True if the console can take the events */
219
220
221 while(SDL_PollEvent(&event))
222 {
223 switch(event.type)
224 {
225 case SDL_KEYDOWN:
226 switch(event.key.keysym.sym)
227 {
228 case SDLK_1:
229 case SDLK_2:
230 case SDLK_3:
231 case SDLK_4:
232 if(event.key.keysym.mod & KMOD_CTRL)
233 {
234 if(ConsoleDisplay[event.key.keysym.sym - SDLK_1])
235 ConsoleDisplay[event.key.keysym.sym - SDLK_1] = 0;
236 else
237 ConsoleDisplay[event.key.keysym.sym - SDLK_1] = 1;
238 break;
239 }
240 else if(event.key.keysym.mod & KMOD_ALT)
241 {
242 if((event.key.keysym.sym - SDLK_1) == CONSOLE_N)
243 {
244 CON_Topmost(NULL);
245 console_events = 0;
246 SDL_EnableUNICODE(0);
247 SDL_EnableKeyRepeat(0,0);
248 }
249 else
250 {
251 CON_Topmost(Consoles[event.key.keysym.sym - SDLK_1]);
252 console_events = 1;
253 SDL_EnableUNICODE(1);
254 SDL_EnableKeyRepeat(250,30);
255 }
256 break;
257 }
258 default:
259 /* Send the event to the console */
260 if(console_events)
261 CON_Events(&event);
262 break;
263 }
264 break;
265 case SDL_QUIT:
266 MainProgram = 0;
267 break;
268 default:
269 break;
270 }
271 }
272 }
273
274 /* call this to end the main loop */
275 void KillProgram(ConsoleInformation *console, char *String)
276 {
277 MainProgram = 0;
278 }
279
280 /* Prints the string you pass it into the console */
281 void Echo(ConsoleInformation *console, char *String)
282 {
283 CON_Out(console, "%s", String);
284 }
285
286 /* This function toggles the draw text demo */
287 void DrawTextDemo(ConsoleInformation *console, char *String)
288 {
289 if(TextDemo == 0)
290 TextDemo = 1;
291 else
292 TextDemo = 0;
293 }
294
295 /* This function demonstrates the text drawing routines that
296 * come with this console */
297 void RandText(SDL_Surface *Screen)
298 {
299 DT_DrawText("This is an example of the DrawText routine", Screen, 0, 40, Screen->h - 20);
300 DT_DrawText("This is an example of the DrawText routine", Screen, 0, 100, 300);
301 DT_DrawText("This is an example of the DrawText routine", Screen, 0, 200, 400);
302 DT_DrawText("This is an example of the DrawText routine", Screen, 0, 20, 20);
303 DT_DrawText("This is an example of the DrawText routine", Screen, 0, 0, 0);
304 DT_DrawText("This is an example of the DrawText routine", Screen, 0, 300, 5);
305 DT_DrawText("This is an example of the DrawText routine", Screen, 0, 600, 90);
306
307 /* Now show the large font */
308 if(-1 != LargeFont)
309 {
310 DT_DrawText("Heres a large font (non-transparent)", Screen, LargeFont, 50, 60);
311 DT_DrawText("Heres a large font (non-transparent)", Screen, LargeFont, 0, 170);
312 }
313 }
314
315 /* lets the user change the alpha level */
316 void AlphaChange(ConsoleInformation *console, char *alpha)
317 {
318 CON_Alpha(console, atoi(alpha));
319 CON_Out(console, "Alpha set to %s.", alpha);
320 }
321
322
323 /* Adds a background image */
324 void AddBackground(ConsoleInformation *console, char *string)
325 {
326 int x, y;
327
328
329 if(2 != sscanf(string, "%d %d", &x, &y))
330 {
331 x = 0;
332 y = 0;
333 }
334
335 if(x == -1 || y == -1)
336 CON_Background(console, NULL, 0, 0);
337 else
338 CON_Background(console, "background.jpg", x, y);
339 }
340
341 /* Move the console, takes and x and a y */
342 void Move(ConsoleInformation *console, char *string)
343 {
344 int x, y;
345
346
347 if(2 != sscanf(string, "%d %d", &x, &y))
348 {
349 x = 0;
350 y = 0;
351 }
352
353 CON_Position(console, x, y);
354 }
355
356 /* resizes the console window, takes and x and y, and a width and height */
357 void Resize(ConsoleInformation *console, char *string)
358 {
359 int x, y, w, h;
360
361 SDL_Rect rect;
362 if(4 != sscanf(string, "%d %d %d %d", &x, &y, &w, &h))
363 {
364 CON_Out(console, "Usage: X Y Width Height");
365 return;
366 }
367 rect.x = x;
368 rect.y = y;
369 rect.w = w;
370 rect.h = h;
371 CON_Resize(console, rect);
372
373 }
374
375 /* Lists all the commands. */
376 void ListCommands(ConsoleInformation *console, char *string)
377 {
378 CON_ListCommands(console);
379 }
380
381 void SetPrompt(ConsoleInformation *console, char *string) {
382 CON_SetPrompt(console, string);
383 }
0 #ifndef ConsoleExample_h
1 #define ConsoleExample_h
2
3
4 int Init(SDL_Surface **Screen, int argc, char **argv);
5 void ProcessEvents();
6 void KillProgram(ConsoleInformation *console, char *String);
7 void Echo(ConsoleInformation *console, char *String);
8 void DrawTextDemo(ConsoleInformation *console, char *String);
9 void RandText(SDL_Surface *Screen);
10 void AlphaChange(ConsoleInformation *console, char *alpha);
11 void AddBackground(ConsoleInformation *console, char *string);
12 void Move(ConsoleInformation *console, char *string);
13 void Resize(ConsoleInformation *console, char *string);
14 void ListCommands(ConsoleInformation *console, char *string);
15 void SetPrompt(ConsoleInformation *console, char *string);
16
17 #endif
18
19
20
Binary diff not shown
Binary diff not shown
0 # Makefile for the SDL_Console example
1
2 CC=gcc
3
4 LIBS=-L.. `sdl-config --libs` -lm -lSDL_console -lSDL_image
5 LIBSSTATIC=-L.. `sdl-config --libs` -lm -lSDL_image ../libSDL_console.a
6 GLLIBS=$(LIBS) -lGL -lGLU -lglut
7
8 FLAGS=-Wall -g -O2
9
10 INCLUDE=`sdl-config --cflags` -I.. -I.
11 GLINCLUDE=$(INCLUDE) -DGL_DEMO
12
13 OBJS=ConsoleExample.o
14 GLOBJS=ConsoleExampleGL.o
15
16 TARGET=ConsoleExample
17 GLTARGET=ConsoleExampleGL
18 STATIC=ConsoleExample-static
19
20 SUBDIRS=..
21
22
23 all: $(TARGET) $(GLTARGET) $(STATIC) FORCE
24 .PHONY: all
25
26 $(SUBDIRS): FORCE
27 @$(MAKE) -C $@
28
29 SUBDIRS_CLEAN = $(SUBDIRS:%=%/clean)
30 $(SUBDIRS_CLEAN): FORCE
31 @$(MAKE) `basename $@` -C `dirname $@`
32 .PHONY: $(SUBDIRS_CLEAN)
33
34 $(TARGET): $(SUBDIRS) $(OBJS)
35 $(CC) $(OBJS) $(FLAGS) $(INCLUDE) $(LIBS) -o $@
36
37 $(STATIC): $(SUBDIRS) $(OBJS)
38 $(CC) $(OBJS) $(FLAGS) $(INCLUDE) $(LIBSSTATIC) -o $@
39
40 %.o: %.c
41 $(CC) $(FLAGS) $(INCLUDE) -c $< -o $@
42
43 %GL.o: %.c
44 $(CC) $(FLAGS) $(GLINCLUDE) -c $< -o $@
45
46 $(GLTARGET): $(SUBDIRS) $(GLOBJS)
47 $(CC) $(FLAGS) $(GLOBJS) $(GLLIBS) -o $@
48
49 clean: $(SUBDIRS_CLEAN) FORCE
50 $(RM) core $(TARGET) $(GLTARGET) $(STATIC) $(OBJS) $(GLOBJS)
51 .PHONY: clean
52
53 FORCE:
54 .PHONY: FORCE
55
56
Binary diff not shown
0 /* internal.c
1 * Written By: Garrett Banuk <mongoose@mongeese.org>
2 * This is free, just be sure to give me credit when using it
3 * in any of your programs.
4 */
5
6 /* internal.[c,h] are various routines used internally
7 * by SDL_console and DrawText. */
8
9 #include "SDL.h"
10
11
12 /*
13 * Return the pixel value at (x, y)
14 * NOTE: The surface must be locked before calling this!
15 */
16 Uint32 DT_GetPixel(SDL_Surface *surface, int x, int y)
17 {
18 int bpp = surface->format->BytesPerPixel;
19 /* Here p is the address to the pixel we want to retrieve */
20 Uint8 *p = (Uint8 *) surface->pixels + y * surface->pitch + x * bpp;
21
22 switch (bpp)
23 {
24 case 1:
25 return *p;
26 case 2:
27 return *(Uint16 *) p;
28 case 3:
29 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
30 return p[0] << 16 | p[1] << 8 | p[2];
31 else
32 return p[0] | p[1] << 8 | p[2] << 16;
33 case 4:
34 return *(Uint32 *) p;
35 default:
36 return 0; /* shouldn't happen, but avoids warnings */
37 }
38 }
39
40 /*
41 * Set the pixel at (x, y) to the given value
42 * NOTE: The surface must be locked before calling this!
43 */
44 void DT_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
45 {
46 int bpp = surface->format->BytesPerPixel;
47 /* Here p is the address to the pixel we want to set */
48 Uint8 *p = (Uint8 *) surface->pixels + y * surface->pitch + x * bpp;
49
50 switch (bpp)
51 {
52 case 1:
53 *p = pixel;
54 break;
55 case 2:
56 *(Uint16 *) p = pixel;
57 break;
58 case 3:
59 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
60 {
61 p[0] = (pixel >> 16) & 0xff;
62 p[1] = (pixel >> 8) & 0xff;
63 p[2] = pixel & 0xff;
64 }
65 else
66 {
67 p[0] = pixel & 0xff;
68 p[1] = (pixel >> 8) & 0xff;
69 p[2] = (pixel >> 16) & 0xff;
70 }
71 break;
72 case 4:
73 *(Uint32 *) p = pixel;
74 break;
75 default:
76 break;
77 }
78 }
79
80
81
0 #ifndef _internal_h_
1 #define _internal_h_
2
3
4 #define PRINT_ERROR(X) fprintf(stderr, "ERROR in %s:%s(): %s\n", __FILE__, __FUNCTION__, X)
5
6 Uint32 DT_GetPixel(SDL_Surface *surface, int x, int y);
7 void DT_PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
8
9
10 #endif /* _internal_h_ */
11
12