From 80f2c6d8322267e6d3affd67487463bfdab56aec Mon Sep 17 00:00:00 2001 From: Bradley Bell Date: Thu, 11 Dec 2014 22:39:52 -0800 Subject: [PATCH] merged CON_console and console --- Makefile.am | 4 - console/CON_console.c | 1111 ------------------------------ d2x.xcodeproj/project.pbxproj | 14 - include/CON_console.h | 210 ------ include/console.h | 109 ++- main/console.c | 1201 ++++++++++++++++++++++++++++++++- 6 files changed, 1302 insertions(+), 1347 deletions(-) delete mode 100644 console/CON_console.c delete mode 100644 include/CON_console.h diff --git a/Makefile.am b/Makefile.am index b07c3c77..8e0226f9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -51,10 +51,6 @@ else d2x_SOURCES += 2d/tmerge.c maths/fixc.c endif -if USE_CONSOLE -d2x_SOURCES += console/CON_console.c -endif - if USE_NETWORK d2x_SOURCES += main/kmatrix.c main/multi.c main/multibot.c main/network.c main/netmisc.c endif diff --git a/console/CON_console.c b/console/CON_console.c deleted file mode 100644 index f9ebf2ab..00000000 --- a/console/CON_console.c +++ /dev/null @@ -1,1111 +0,0 @@ -/* CON_console.c - * Written By: Garrett Banuk - * Code Cleanup and heavily extended by: Clemens Wacha - * Ported to use native Descent interfaces by: Bradley Bell - * - * This is free, just be sure to give us credit when using it - * in any of your programs. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#include "CON_console.h" - -#include "u_mem.h" -#include "gr.h" -#include "timer.h" - - -#define FG_COLOR grd_curcanv->cv_font_fg_color -#define get_msecs() approx_fsec_to_msec(timer_get_approx_seconds()) - - -/* This contains a pointer to the "topmost" console. The console that - * is currently taking keyboard input. */ -static ConsoleInformation *Topmost; - -/* Takes keys from the keyboard and inputs them to the console - If the event was not handled (i.e. WM events or unknown ctrl-shift - sequences) the function returns the event for further processing. */ -int CON_Events(int event) -{ - if(Topmost == NULL) - return event; - if(!CON_isVisible(Topmost)) - return event; - - if(event & KEY_CTRLED) - { - //CTRL pressed - switch(event & ~KEY_CTRLED) - { - case KEY_A: - Cursor_Home(Topmost); - break; - case KEY_E: - Cursor_End(Topmost); - break; - case KEY_C: - Clear_Command(Topmost); - break; - case KEY_L: - Clear_History(Topmost); - CON_UpdateConsole(Topmost); - break; - default: - return event; - } - } - else if(event & KEY_ALTED) - { - //the console does not handle ALT combinations! - return event; - } - else - { - //first of all, check if the console hide key was pressed - if(event == Topmost->HideKey) - { - CON_Hide(Topmost); - return 0; - } - switch (event & 0xff) - { - case KEY_LSHIFT: - case KEY_RSHIFT: - return event; - case KEY_HOME: - if(event & KEY_SHIFTED) - { - Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; - CON_UpdateConsole(Topmost); - } else { - Cursor_Home(Topmost); - } - break; - case KEY_END: - if(event & KEY_SHIFTED) - { - Topmost->ConsoleScrollBack = 0; - CON_UpdateConsole(Topmost); - } else { - Cursor_End(Topmost); - } - break; - case KEY_PAGEUP: - Topmost->ConsoleScrollBack += CON_LINE_SCROLL; - if(Topmost->ConsoleScrollBack > Topmost->LineBuffer-1) - Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; - - CON_UpdateConsole(Topmost); - break; - case KEY_PAGEDOWN: - Topmost->ConsoleScrollBack -= CON_LINE_SCROLL; - if(Topmost->ConsoleScrollBack < 0) - Topmost->ConsoleScrollBack = 0; - CON_UpdateConsole(Topmost); - break; - case KEY_UP: - Command_Up(Topmost); - break; - case KEY_DOWN: - Command_Down(Topmost); - break; - case KEY_LEFT: - Cursor_Left(Topmost); - break; - case KEY_RIGHT: - Cursor_Right(Topmost); - break; - case KEY_BACKSP: - Cursor_BSpace(Topmost); - break; - case KEY_DELETE: - Cursor_Del(Topmost); - break; - case KEY_INSERT: - Topmost->InsMode = 1-Topmost->InsMode; - break; - case KEY_TAB: - CON_TabCompletion(Topmost); - break; - case KEY_ENTER: - if(strlen(Topmost->Command) > 0) { - CON_NewLineCommand(Topmost); - - // copy the input into the past commands strings - strcpy(Topmost->CommandLines[0], Topmost->Command); - - // display the command including the prompt - CON_Out(Topmost, "%s%s", Topmost->Prompt, Topmost->Command); - CON_UpdateConsole(Topmost); - - CON_Execute(Topmost, Topmost->Command); - //printf("Command: %s\n", Topmost->Command); - - Clear_Command(Topmost); - Topmost->CommandScrollBack = -1; - } - break; - case KEY_LAPOSTRO: - //deactivate Console - CON_Hide(Topmost); - return 0; - default: - if (key_to_ascii(event) == 255) - break; - if(Topmost->InsMode) - Cursor_Add(Topmost, event); - else { - Cursor_Add(Topmost, event); - Cursor_Del(Topmost); - } - } - } - return 0; -} - -#if 0 -/* CON_AlphaGL() -- sets the alpha channel of an SDL_Surface to the - * specified value. Preconditions: the surface in question is RGBA. - * 0 <= a <= 255, where 0 is transparent and 255 is opaque. */ -void CON_AlphaGL(SDL_Surface *s, int alpha) { - Uint8 val; - int x, y, w, h; - Uint32 pixel; - Uint8 r, g, b, a; - SDL_PixelFormat *format; - static char errorPrinted = 0; - - - /* debugging assertions -- these slow you down, but hey, crashing sucks */ - if(!s) { - PRINT_ERROR("NULL Surface passed to CON_AlphaGL\n"); - return; - } - - /* clamp alpha value to 0...255 */ - if(alpha < SDL_ALPHA_TRANSPARENT) - val = SDL_ALPHA_TRANSPARENT; - else if(alpha > SDL_ALPHA_OPAQUE) - val = SDL_ALPHA_OPAQUE; - else - val = alpha; - - /* loop over alpha channels of each pixel, setting them appropriately. */ - w = s->w; - h = s->h; - format = s->format; - switch (format->BytesPerPixel) { - case 2: - /* 16-bit surfaces don't seem to support alpha channels. */ - if(!errorPrinted) { - errorPrinted = 1; - PRINT_ERROR("16-bit SDL surfaces do not support alpha-blending under OpenGL.\n"); - } - break; - case 4: { - /* we can do this very quickly in 32-bit mode. 24-bit is more - * difficult. And since 24-bit mode is reall the same as 32-bit, - * so it usually ends up taking this route too. Win! Unroll loop - * and use pointer arithmetic for extra speed. */ - int numpixels = h * (w << 2); - Uint8 *pix = (Uint8 *) (s->pixels); - Uint8 *last = pix + numpixels; - Uint8 *pixel; - if((numpixels & 0x7) == 0) - for(pixel = pix + 3; pixel < last; pixel += 32) - *pixel = *(pixel + 4) = *(pixel + 8) = *(pixel + 12) = *(pixel + 16) = *(pixel + 20) = *(pixel + 24) = *(pixel + 28) = val; - else - for(pixel = pix + 3; pixel < last; pixel += 4) - *pixel = val; - break; - } - default: - /* we have no choice but to do this slowly. */ - for(y = 0; y < h; ++y) - for(x = 0; x < w; ++x) { - char print = 0; - /* Lock the surface for direct access to the pixels */ - if(SDL_MUSTLOCK(s) && SDL_LockSurface(s) < 0) { - PRINT_ERROR("Can't lock surface: "); - fprintf(stderr, "%s\n", SDL_GetError()); - return; - } - pixel = DT_GetPixel(s, x, y); - if(x == 0 && y == 0) - print = 1; - SDL_GetRGBA(pixel, format, &r, &g, &b, &a); - pixel = SDL_MapRGBA(format, r, g, b, val); - SDL_GetRGBA(pixel, format, &r, &g, &b, &a); - DT_PutPixel(s, x, y, pixel); - - /* unlock surface again */ - if(SDL_MUSTLOCK(s)) - SDL_UnlockSurface(s); - } - break; - } -} -#endif - - -/* Updates the console buffer */ -void CON_UpdateConsole(ConsoleInformation *console) { - int loop; - int loop2; - int Screenlines; - grs_canvas *canv_save; - short orig_color; - - if(!console) - return; - - /* Due to the Blits, the update is not very fast: So only update if it's worth it */ - if(!CON_isVisible(console)) - return; - - Screenlines = console->ConsoleSurface->cv_h / (CON_LINE_SPACE + console->ConsoleSurface->cv_font->ft_h); - - canv_save = grd_curcanv; - gr_set_current_canvas(console->ConsoleSurface); - -#if 0 - SDL_FillRect(console->ConsoleSurface, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, console->ConsoleAlpha)); -#else - //gr_rect(0,0, -#endif - -#if 0 - if(console->OutputScreen->flags & SDL_OPENGLBLIT) - SDL_SetAlpha(console->ConsoleSurface, 0, SDL_ALPHA_OPAQUE); -#endif - - /* draw the background image if there is one */ - if(console->BackgroundImage) - gr_bitmap(0, 0, console->BackgroundImage); - - /* Draw the text from the back buffers, calculate in the scrollback from the user - * this is a normal SDL software-mode blit, so we need to temporarily set the ColorKey - * for the font, and then clear it when we're done. - */ -#if 0 - if((console->OutputScreen->flags & SDL_OPENGLBLIT) && (console->OutputScreen->format->BytesPerPixel > 2)) { - Uint32 *pix = (Uint32 *) (CurrentFont->FontSurface->pixels); - SDL_SetColorKey(CurrentFont->FontSurface, SDL_SRCCOLORKEY, *pix); - } -#endif - - //now draw text from last but second line to top - for(loop = 0; loop < Screenlines-1 && loop < console->LineBuffer - console->ConsoleScrollBack; loop++) { - if(console->ConsoleScrollBack != 0 && loop == 0) - for(loop2 = 0; loop2 < (console->VChars / 5) + 1; loop2++) - { - orig_color = FG_COLOR; - gr_string(CON_CHAR_BORDER + (loop2*5*console->ConsoleSurface->cv_font->ft_w), (Screenlines - loop - 2) * (CON_LINE_SPACE + console->ConsoleSurface->cv_font->ft_h), CON_SCROLL_INDICATOR); - FG_COLOR = orig_color; - } - else - { - orig_color = FG_COLOR; - gr_string(CON_CHAR_BORDER, (Screenlines - loop - 2) * (CON_LINE_SPACE + console->ConsoleSurface->cv_font->ft_h), console->ConsoleLines[console->ConsoleScrollBack + loop]); - FG_COLOR = orig_color; - } - } - - gr_set_current_canvas(canv_save); - -#if 0 - if(console->OutputScreen->flags & SDL_OPENGLBLIT) - SDL_SetColorKey(CurrentFont->FontSurface, 0, 0); -#endif -} - -void CON_UpdateOffset(ConsoleInformation* console) { - if(!console) - return; - - switch(console->Visible) { - case CON_CLOSING: - console->RaiseOffset -= CON_OPENCLOSE_SPEED; - if(console->RaiseOffset <= 0) { - console->RaiseOffset = 0; - console->Visible = CON_CLOSED; - } - break; - case CON_OPENING: - console->RaiseOffset += CON_OPENCLOSE_SPEED; - if(console->RaiseOffset >= console->ConsoleSurface->cv_h) { - console->RaiseOffset = console->ConsoleSurface->cv_h; - console->Visible = CON_OPEN; - } - break; - case CON_OPEN: - case CON_CLOSED: - break; - } -} - -/* Draws the console buffer to the screen if the console is "visible" */ -void CON_DrawConsole(ConsoleInformation *console) { - grs_canvas *canv_save; - grs_bitmap *clip; - - if(!console) - return; - - /* only draw if console is visible: here this means, that the console is not CON_CLOSED */ - if(console->Visible == CON_CLOSED) - return; - - /* Update the scrolling offset */ - CON_UpdateOffset(console); - - /* Update the command line since it has a blinking cursor */ - DrawCommandLine(); - -#if 0 - /* before drawing, make sure the alpha channel of the console surface is set - * properly. (sigh) I wish we didn't have to do this every frame... */ - if(console->OutputScreen->flags & SDL_OPENGLBLIT) - CON_AlphaGL(console->ConsoleSurface, console->ConsoleAlpha); -#endif - - canv_save = grd_curcanv; - gr_set_current_canvas(&console->OutputScreen->sc_canvas); - - clip = gr_create_sub_bitmap(&console->ConsoleSurface->cv_bitmap, 0, console->ConsoleSurface->cv_h - console->RaiseOffset, console->ConsoleSurface->cv_w, console->RaiseOffset); - - gr_bitmap(console->DispX, console->DispY, clip); - gr_free_sub_bitmap(clip); - -#if 0 - if(console->OutputScreen->flags & SDL_OPENGLBLIT) - SDL_UpdateRects(console->OutputScreen, 1, &DestRect); -#endif - - gr_set_current_canvas(canv_save); -} - - -/* Initializes the console */ -ConsoleInformation *CON_Init(grs_font *Font, grs_screen *DisplayScreen, int lines, int x, int y, int w, int h) -{ - int loop; - ConsoleInformation *newinfo; - - - /* Create a new console struct and init it. */ - if((newinfo = (ConsoleInformation *) d_malloc(sizeof(ConsoleInformation))) == NULL) { - //PRINT_ERROR("Could not allocate the space for a new console info struct.\n"); - return NULL; - } - newinfo->Visible = CON_CLOSED; - newinfo->RaiseOffset = 0; - newinfo->ConsoleLines = NULL; - newinfo->CommandLines = NULL; - newinfo->TotalConsoleLines = 0; - newinfo->ConsoleScrollBack = 0; - newinfo->TotalCommands = 0; - newinfo->BackgroundImage = NULL; -#if 0 - newinfo->ConsoleAlpha = SDL_ALPHA_OPAQUE; -#endif - newinfo->Offset = 0; - newinfo->InsMode = 1; - newinfo->CursorPos = 0; - newinfo->CommandScrollBack = 0; - newinfo->OutputScreen = DisplayScreen; - newinfo->Prompt = CON_DEFAULT_PROMPT; - newinfo->HideKey = CON_DEFAULT_HIDEKEY; - - CON_SetExecuteFunction(newinfo, Default_CmdFunction); - CON_SetTabCompletion(newinfo, Default_TabFunction); - CON_SetHideFunction(newinfo, Default_HideFunction); - - /* make sure that the size of the console is valid */ - if(w > newinfo->OutputScreen->sc_w || w < Font->ft_w * 32) - w = newinfo->OutputScreen->sc_w; - if(h > newinfo->OutputScreen->sc_h || h < Font->ft_h) - h = newinfo->OutputScreen->sc_h; - if(x < 0 || x > newinfo->OutputScreen->sc_w - w) - newinfo->DispX = 0; - else - newinfo->DispX = x; - if(y < 0 || y > newinfo->OutputScreen->sc_h - h) - newinfo->DispY = 0; - else - newinfo->DispY = y; - - /* load the console surface */ - newinfo->ConsoleSurface = gr_create_canvas(w, h); - - /* Load the consoles font */ - { - grs_canvas *canv_save; - - canv_save = grd_curcanv; - gr_set_current_canvas(newinfo->ConsoleSurface); - gr_set_curfont(Font); - gr_set_fontcolor(gr_getcolor(63,63,63), -1); - gr_set_current_canvas(canv_save); - } - - - /* Load the dirty rectangle for user input */ - newinfo->InputBackground = gr_create_bitmap(w, newinfo->ConsoleSurface->cv_font->ft_h); -#if 0 - SDL_FillRect(newinfo->InputBackground, NULL, SDL_MapRGBA(newinfo->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); -#endif - - /* calculate the number of visible characters in the command line */ - newinfo->VChars = (w - CON_CHAR_BORDER) / newinfo->ConsoleSurface->cv_font->ft_w; - if(newinfo->VChars > CON_CHARS_PER_LINE) - newinfo->VChars = CON_CHARS_PER_LINE; - - /* We would like to have a minumum # of lines to guarentee we don't create a memory error */ - if(h / (CON_LINE_SPACE + newinfo->ConsoleSurface->cv_font->ft_h) > lines) - newinfo->LineBuffer = h / (CON_LINE_SPACE + newinfo->ConsoleSurface->cv_font->ft_h); - else - newinfo->LineBuffer = lines; - - - newinfo->ConsoleLines = (char **)d_malloc(sizeof(char *) * newinfo->LineBuffer); - newinfo->CommandLines = (char **)d_malloc(sizeof(char *) * newinfo->LineBuffer); - for(loop = 0; loop <= newinfo->LineBuffer - 1; loop++) { - newinfo->ConsoleLines[loop] = (char *)d_calloc(CON_CHARS_PER_LINE, sizeof(char)); - newinfo->CommandLines[loop] = (char *)d_calloc(CON_CHARS_PER_LINE, sizeof(char)); - } - memset(newinfo->Command, 0, CON_CHARS_PER_LINE); - memset(newinfo->LCommand, 0, CON_CHARS_PER_LINE); - memset(newinfo->RCommand, 0, CON_CHARS_PER_LINE); - memset(newinfo->VCommand, 0, CON_CHARS_PER_LINE); - - - CON_Out(newinfo, "Console initialised."); - CON_NewLineConsole(newinfo); - //CON_ListCommands(newinfo); - - return newinfo; -} - -/* Makes the console visible */ -void CON_Show(ConsoleInformation *console) { - if(console) { - console->Visible = CON_OPENING; - CON_UpdateConsole(console); - } -} - -/* Hides the console (make it invisible) */ -void CON_Hide(ConsoleInformation *console) { - if(console) - console->Visible = CON_CLOSING; - console->HideFunction(); -} - -/* tells wether the console is visible or not */ -int CON_isVisible(ConsoleInformation *console) { - if(!console) - return CON_CLOSED; - return((console->Visible == CON_OPEN) || (console->Visible == CON_OPENING)); -} - -/* Frees all the memory loaded by the console */ -void CON_Destroy(ConsoleInformation *console) { - CON_Free(console); -} - -/* Frees all the memory loaded by the console */ -void CON_Free(ConsoleInformation *console) { - int i; - - if(!console) - return; - - //CON_DestroyCommands(); - for(i = 0; i <= console->LineBuffer - 1; i++) { - d_free(console->ConsoleLines[i]); - d_free(console->CommandLines[i]); - } - d_free(console->ConsoleLines); - d_free(console->CommandLines); - - console->ConsoleLines = NULL; - console->CommandLines = NULL; - - gr_free_canvas(console->ConsoleSurface); - console->ConsoleSurface = NULL; - - if (console->BackgroundImage) - gr_free_bitmap(console->BackgroundImage); - console->BackgroundImage = NULL; - - gr_free_bitmap(console->InputBackground); - console->InputBackground = NULL; - - d_free(console); -} - - -/* Increments the console lines */ -void CON_NewLineConsole(ConsoleInformation *console) { - int loop; - char* temp; - - if(!console) - return; - - temp = console->ConsoleLines[console->LineBuffer - 1]; - - for(loop = console->LineBuffer - 1; loop > 0; loop--) - console->ConsoleLines[loop] = console->ConsoleLines[loop - 1]; - - console->ConsoleLines[0] = temp; - - memset(console->ConsoleLines[0], 0, CON_CHARS_PER_LINE); - if(console->TotalConsoleLines < console->LineBuffer - 1) - console->TotalConsoleLines++; - - //Now adjust the ConsoleScrollBack - //dont scroll if not at bottom - if(console->ConsoleScrollBack != 0) - console->ConsoleScrollBack++; - //boundaries - if(console->ConsoleScrollBack > console->LineBuffer-1) - console->ConsoleScrollBack = console->LineBuffer-1; - -} - - -/* Increments the command lines */ -void CON_NewLineCommand(ConsoleInformation *console) { - int loop; - char *temp; - - if(!console) - return; - - temp = console->CommandLines[console->LineBuffer - 1]; - - - for(loop = console->LineBuffer - 1; loop > 0; loop--) - console->CommandLines[loop] = console->CommandLines[loop - 1]; - - console->CommandLines[0] = temp; - - memset(console->CommandLines[0], 0, CON_CHARS_PER_LINE); - if(console->TotalCommands < console->LineBuffer - 1) - console->TotalCommands++; -} - -/* Draws the command line the user is typing in to the screen */ -/* completely rewritten by C.Wacha */ -void DrawCommandLine() { - int x; - int commandbuffer; -#if 0 - grs_font* CurrentFont; -#endif - static unsigned int LastBlinkTime = 0; /* Last time the consoles cursor blinked */ - static int LastCursorPos = 0; // Last Cursor Position - static int Blink = 0; /* Is the cursor currently blinking */ - grs_canvas *canv_save; - short orig_color; - - if(!Topmost) - return; - - commandbuffer = Topmost->VChars - strlen(Topmost->Prompt)-1; // -1 to make cursor visible - -#if 0 - CurrentFont = Topmost->ConsoleSurface->cv_font; -#endif - - //Concatenate the left and right side to command - strcpy(Topmost->Command, Topmost->LCommand); - strncat(Topmost->Command, Topmost->RCommand, strlen(Topmost->RCommand)); - - //calculate display offset from current cursor position - if(Topmost->Offset < Topmost->CursorPos - commandbuffer) - Topmost->Offset = Topmost->CursorPos - commandbuffer; - if(Topmost->Offset > Topmost->CursorPos) - Topmost->Offset = Topmost->CursorPos; - - //first add prompt to visible part - strcpy(Topmost->VCommand, Topmost->Prompt); - - //then add the visible part of the command - strncat(Topmost->VCommand, &Topmost->Command[Topmost->Offset], strlen(&Topmost->Command[Topmost->Offset])); - - //now display the result - -#if 0 - //once again we're drawing text, so in OpenGL context we need to temporarily set up - //software-mode transparency. - if(Topmost->OutputScreen->flags & SDL_OPENGLBLIT) { - Uint32 *pix = (Uint32 *) (CurrentFont->FontSurface->pixels); - SDL_SetColorKey(CurrentFont->FontSurface, SDL_SRCCOLORKEY, *pix); - } -#endif - - canv_save = grd_curcanv; - gr_set_current_canvas(Topmost->ConsoleSurface); - - //first of all restore InputBackground - gr_bitmap(0, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->InputBackground); - - //now add the text - orig_color = FG_COLOR; - gr_string(CON_CHAR_BORDER, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->VCommand); - FG_COLOR = orig_color; - - //at last add the cursor - //check if the blink period is over - if(get_msecs() > LastBlinkTime) { - LastBlinkTime = get_msecs() + CON_BLINK_RATE; - if(Blink) - Blink = 0; - else - Blink = 1; - } - - //check if cursor has moved - if yes display cursor anyway - if(Topmost->CursorPos != LastCursorPos) { - LastCursorPos = Topmost->CursorPos; - LastBlinkTime = get_msecs() + CON_BLINK_RATE; - Blink = 1; - } - - if(Blink) { - int prompt_width, cmd_width, h, w; - - gr_get_string_size(Topmost->Prompt, &prompt_width, &h, &w); - gr_get_string_size(Topmost->LCommand + Topmost->Offset, &cmd_width, &h, &w); - x = CON_CHAR_BORDER + prompt_width + cmd_width; - orig_color = FG_COLOR; - if(Topmost->InsMode) - gr_string(x, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, CON_INS_CURSOR); - else - gr_string(x, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, CON_OVR_CURSOR); - FG_COLOR = orig_color; - } - - gr_set_current_canvas(canv_save); - - -#if 0 - if(Topmost->OutputScreen->flags & SDL_OPENGLBLIT) { - SDL_SetColorKey(CurrentFont->FontSurface, 0, 0); - } -#endif -} - -#ifdef _MSC_VER -# define vsnprintf _vsnprintf -#endif - -/* Outputs text to the console (in game), up to CON_CHARS_PER_LINE chars can be entered */ -void CON_Out(ConsoleInformation *console, const char *str, ...) { - va_list marker; - //keep some space free for stuff like CON_Out(console, "blablabla %s", console->Command); - char temp[CON_CHARS_PER_LINE + 128]; - char* ptemp; - - if(!console) - return; - - va_start(marker, str); - vsnprintf(temp, CON_CHARS_PER_LINE + 127, str, marker); - va_end(marker); - - ptemp = temp; - - //temp now contains the complete string we want to output - // the only problem is that temp is maybe longer than the console - // width so we have to cut it into several pieces - - if(console->ConsoleLines) { - while(strlen(ptemp) > console->VChars) { - CON_NewLineConsole(console); - strncpy(console->ConsoleLines[0], ptemp, console->VChars); - console->ConsoleLines[0][console->VChars] = '\0'; - ptemp = &ptemp[console->VChars]; - } - CON_NewLineConsole(console); - strncpy(console->ConsoleLines[0], ptemp, console->VChars); - console->ConsoleLines[0][console->VChars] = '\0'; - CON_UpdateConsole(console); - } - - /* And print to stdout */ - //printf("%s\n", temp); -} - - -#if 0 -/* Sets the alpha level of the console, 0 turns off alpha blending */ -void CON_Alpha(ConsoleInformation *console, unsigned char alpha) { - if(!console) - return; - - /* store alpha as state! */ - console->ConsoleAlpha = alpha; - - if((console->OutputScreen->flags & SDL_OPENGLBLIT) == 0) { - if(alpha == 0) - SDL_SetAlpha(console->ConsoleSurface, 0, alpha); - else - SDL_SetAlpha(console->ConsoleSurface, SDL_SRCALPHA, alpha); - } - - // CON_UpdateConsole(console); -} -#endif - - -/* Adds background image to the console, scaled to size of console*/ -int CON_Background(ConsoleInformation *console, grs_bitmap *image) -{ - if(!console) - return 1; - - /* Free the background from the console */ - if (image == NULL) { - if (console->BackgroundImage) - gr_free_bitmap(console->BackgroundImage); - console->BackgroundImage = NULL; -#if 0 - SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); -#endif - return 0; - } - - /* Load a new background */ - if (console->BackgroundImage) - gr_free_bitmap(console->BackgroundImage); - console->BackgroundImage = gr_create_bitmap(console->ConsoleSurface->cv_w, console->ConsoleSurface->cv_h); - gr_bitmap_scale_to(image, console->BackgroundImage); - -#if 0 - SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); -#endif - gr_bm_bitblt(console->BackgroundImage->bm_w, console->InputBackground->bm_h, 0, 0, 0, console->ConsoleSurface->cv_h - console->ConsoleSurface->cv_font->ft_h, console->BackgroundImage, console->InputBackground); - - return 0; -} - -/* Sets font info for the console */ -void CON_Font(ConsoleInformation *console, grs_font *font, int fg, int bg) -{ - grs_canvas *canv_save; - - canv_save = grd_curcanv; - gr_set_current_canvas(console->ConsoleSurface); - gr_set_curfont(font); - gr_set_fontcolor(fg, bg); - gr_set_current_canvas(canv_save); -} - -/* takes a new x and y of the top left of the console window */ -void CON_Position(ConsoleInformation *console, int x, int y) { - if(!console) - return; - - if(x < 0 || x > console->OutputScreen->sc_w - console->ConsoleSurface->cv_w) - console->DispX = 0; - else - console->DispX = x; - - if(y < 0 || y > console->OutputScreen->sc_h - console->ConsoleSurface->cv_h) - console->DispY = 0; - else - console->DispY = y; -} - -void gr_init_bitmap_alloc( grs_bitmap *bm, int mode, int x, int y, int w, int h, int bytesperline); -/* resizes the console, has to reset alot of stuff - * returns 1 on error */ -int CON_Resize(ConsoleInformation *console, int x, int y, int w, int h) -{ - if(!console) - return 1; - - /* make sure that the size of the console is valid */ - if(w > console->OutputScreen->sc_w || w < console->ConsoleSurface->cv_font->ft_w * 32) - w = console->OutputScreen->sc_w; - if(h > console->OutputScreen->sc_h || h < console->ConsoleSurface->cv_font->ft_h) - h = console->OutputScreen->sc_h; - if(x < 0 || x > console->OutputScreen->sc_w - w) - console->DispX = 0; - else - console->DispX = x; - if(y < 0 || y > console->OutputScreen->sc_h - h) - console->DispY = 0; - else - console->DispY = y; - - /* resize console surface */ - gr_free_bitmap_data(&console->ConsoleSurface->cv_bitmap); - gr_init_bitmap_alloc(&console->ConsoleSurface->cv_bitmap, BM_LINEAR, 0, 0, w, h, w); - - /* Load the dirty rectangle for user input */ - gr_free_bitmap(console->InputBackground); - console->InputBackground = gr_create_bitmap(w, console->ConsoleSurface->cv_font->ft_h); - - /* Now reset some stuff dependent on the previous size */ - console->ConsoleScrollBack = 0; - - /* Reload the background image (for the input text area) in the console */ - if(console->BackgroundImage) { -#if 0 - SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); -#endif - gr_bm_bitblt(console->BackgroundImage->bm_w, console->InputBackground->bm_h, 0, 0, 0, console->ConsoleSurface->cv_h - console->ConsoleSurface->cv_font->ft_h, console->BackgroundImage, console->InputBackground); - } - -#if 0 - /* restore the alpha level */ - CON_Alpha(console, console->ConsoleAlpha); -#endif - return 0; -} - -/* Transfers the console to another screen surface, and adjusts size */ -int CON_Transfer(ConsoleInformation *console, grs_screen *new_outputscreen, int x, int y, int w, int h) -{ - if(!console) - return 1; - - console->OutputScreen = new_outputscreen; - - return(CON_Resize(console, x, y, w, h)); -} - -/* Sets the topmost console for input */ -void CON_Topmost(ConsoleInformation *console) { - grs_canvas *canv_save; - short orig_color; - - if(!console) - return; - - // Make sure the blinking cursor is gone - if(Topmost) { - canv_save = grd_curcanv; - gr_set_current_canvas(Topmost->ConsoleSurface); - - gr_bitmap(0, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->InputBackground); - orig_color = FG_COLOR; - gr_string(CON_CHAR_BORDER, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->VCommand); - FG_COLOR = orig_color; - - gr_set_current_canvas(canv_save); - } - Topmost = console; -} - -/* Sets the Prompt for console */ -void CON_SetPrompt(ConsoleInformation *console, char* newprompt) { - if(!console) - return; - - //check length so we can still see at least 1 char :-) - if(strlen(newprompt) < console->VChars) - console->Prompt = d_strdup(newprompt); - else - CON_Out(console, "prompt too long. (max. %i chars)", console->VChars - 1); -} - -/* Sets the key that deactivates (hides) the console. */ -void CON_SetHideKey(ConsoleInformation *console, int key) { - if(console) - console->HideKey = key; -} - -void CON_SetHideFunction(ConsoleInformation *console, void(*HideFunction)(void)) { - if(console) - console->HideFunction = HideFunction; -} - -void Default_HideFunction(void) { -} - -/* Executes the command entered */ -void CON_Execute(ConsoleInformation *console, char* command) { - if(console) - console->CmdFunction(console, command); -} - -void CON_SetExecuteFunction(ConsoleInformation *console, void(*CmdFunction)(ConsoleInformation *console2, char* command)) { - if(console) - console->CmdFunction = CmdFunction; -} - -void Default_CmdFunction(ConsoleInformation *console, char* command) { - CON_Out(console, " No CommandFunction registered"); - CON_Out(console, " use 'CON_SetExecuteFunction' to register one"); - CON_Out(console, " "); - CON_Out(console, "Unknown Command \"%s\"", command); -} - -void CON_SetTabCompletion(ConsoleInformation *console, char*(*TabFunction)(char* command)) { - if(console) - console->TabFunction = TabFunction; -} - -void CON_TabCompletion(ConsoleInformation *console) { - int i,j; - char* command; - - if(!console) - return; - - command = d_strdup(console->LCommand); - command = console->TabFunction(command); - - if(!command) - return; //no tab completion took place so return silently - - j = strlen(command); - if(j > CON_CHARS_PER_LINE - 2) - j = CON_CHARS_PER_LINE-1; - - memset(console->LCommand, 0, CON_CHARS_PER_LINE); - console->CursorPos = 0; - - for(i = 0; i < j; i++) { - console->CursorPos++; - console->LCommand[i] = command[i]; - } - //add a trailing space - console->CursorPos++; - console->LCommand[j] = ' '; - console->LCommand[j+1] = '\0'; -} - -char* Default_TabFunction(char* command) { - CON_Out(Topmost, " No TabFunction registered"); - CON_Out(Topmost, " use 'CON_SetTabCompletion' to register one"); - CON_Out(Topmost, " "); - return NULL; -} - -void Cursor_Left(ConsoleInformation *console) { - char temp[CON_CHARS_PER_LINE]; - - if(Topmost->CursorPos > 0) { - Topmost->CursorPos--; - strcpy(temp, Topmost->RCommand); - strcpy(Topmost->RCommand, &Topmost->LCommand[strlen(Topmost->LCommand)-1]); - strcat(Topmost->RCommand, temp); - Topmost->LCommand[strlen(Topmost->LCommand)-1] = '\0'; - //CON_Out(Topmost, "L:%s, R:%s", Topmost->LCommand, Topmost->RCommand); - } -} - -void Cursor_Right(ConsoleInformation *console) { - char temp[CON_CHARS_PER_LINE]; - - if(Topmost->CursorPos < strlen(Topmost->Command)) { - Topmost->CursorPos++; - strncat(Topmost->LCommand, Topmost->RCommand, 1); - strcpy(temp, Topmost->RCommand); - strcpy(Topmost->RCommand, &temp[1]); - //CON_Out(Topmost, "L:%s, R:%s", Topmost->LCommand, Topmost->RCommand); - } -} - -void Cursor_Home(ConsoleInformation *console) { - char temp[CON_CHARS_PER_LINE]; - - Topmost->CursorPos = 0; - strcpy(temp, Topmost->RCommand); - strcpy(Topmost->RCommand, Topmost->LCommand); - strncat(Topmost->RCommand, temp, strlen(temp)); - memset(Topmost->LCommand, 0, CON_CHARS_PER_LINE); -} - -void Cursor_End(ConsoleInformation *console) { - Topmost->CursorPos = strlen(Topmost->Command); - strncat(Topmost->LCommand, Topmost->RCommand, strlen(Topmost->RCommand)); - memset(Topmost->RCommand, 0, CON_CHARS_PER_LINE); -} - -void Cursor_Del(ConsoleInformation *console) { - char temp[CON_CHARS_PER_LINE]; - - if(strlen(Topmost->RCommand) > 0) { - strcpy(temp, Topmost->RCommand); - strcpy(Topmost->RCommand, &temp[1]); - } -} - -void Cursor_BSpace(ConsoleInformation *console) { - if(Topmost->CursorPos > 0) { - Topmost->CursorPos--; - Topmost->Offset--; - if(Topmost->Offset < 0) - Topmost->Offset = 0; - Topmost->LCommand[strlen(Topmost->LCommand)-1] = '\0'; - } -} - -void Cursor_Add(ConsoleInformation *console, int event) -{ - if(strlen(Topmost->Command) < CON_CHARS_PER_LINE - 1) - { - Topmost->CursorPos++; - Topmost->LCommand[strlen(Topmost->LCommand)] = key_to_ascii(event); - Topmost->LCommand[strlen(Topmost->LCommand)] = '\0'; - } -} - -void Clear_Command(ConsoleInformation *console) { - Topmost->CursorPos = 0; - memset(Topmost->VCommand, 0, CON_CHARS_PER_LINE); - memset(Topmost->Command, 0, CON_CHARS_PER_LINE); - memset(Topmost->LCommand, 0, CON_CHARS_PER_LINE); - memset(Topmost->RCommand, 0, CON_CHARS_PER_LINE); -} - -void Clear_History(ConsoleInformation *console) { - int loop; - - for(loop = 0; loop <= console->LineBuffer - 1; loop++) - memset(console->ConsoleLines[loop], 0, CON_CHARS_PER_LINE); -} - -void Command_Up(ConsoleInformation *console) { - if(console->CommandScrollBack < console->TotalCommands - 1) { - /* move back a line in the command strings and copy the command to the current input string */ - console->CommandScrollBack++; - memset(console->RCommand, 0, CON_CHARS_PER_LINE); - console->Offset = 0; - strcpy(console->LCommand, console->CommandLines[console->CommandScrollBack]); - console->CursorPos = strlen(console->CommandLines[console->CommandScrollBack]); - CON_UpdateConsole(console); - } -} - -void Command_Down(ConsoleInformation *console) { - if(console->CommandScrollBack > -1) { - /* move forward a line in the command strings and copy the command to the current input string */ - console->CommandScrollBack--; - memset(console->RCommand, 0, CON_CHARS_PER_LINE); - memset(console->LCommand, 0, CON_CHARS_PER_LINE); - console->Offset = 0; - if(console->CommandScrollBack > -1) - strcpy(console->LCommand, console->CommandLines[console->CommandScrollBack]); - console->CursorPos = strlen(console->LCommand); - CON_UpdateConsole(console); - } -} - diff --git a/d2x.xcodeproj/project.pbxproj b/d2x.xcodeproj/project.pbxproj index 7ebd4c0f..125a7b8b 100644 --- a/d2x.xcodeproj/project.pbxproj +++ b/d2x.xcodeproj/project.pbxproj @@ -60,7 +60,6 @@ 146697F91A2729870070D41D /* mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = 1466959D1A2729860070D41D /* mouse.c */; }; 146697FA1A2729870070D41D /* rbaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 1466959E1A2729860070D41D /* rbaudio.c */; }; 146697FB1A2729870070D41D /* timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 1466959F1A2729860070D41D /* timer.c */; }; - 146698291A2729870070D41D /* CON_console.c in Sources */ = {isa = PBXBuildFile; fileRef = 146695ED1A2729860070D41D /* CON_console.c */; }; 146698441A2729870070D41D /* iff.c in Sources */ = {isa = PBXBuildFile; fileRef = 146696111A2729860070D41D /* iff.c */; }; 1466984B1A2729870070D41D /* decoder16.c in Sources */ = {isa = PBXBuildFile; fileRef = 146696481A2729870070D41D /* decoder16.c */; }; 1466984C1A2729870070D41D /* decoder8.c in Sources */ = {isa = PBXBuildFile; fileRef = 146696491A2729870070D41D /* decoder8.c */; }; @@ -423,7 +422,6 @@ 146695E91A2729860070D41D /* win32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = win32.c; sourceTree = ""; }; 146695EA1A2729860070D41D /* winmain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = winmain.cpp; sourceTree = ""; }; 146695EB1A2729860070D41D /* winnet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = winnet.c; sourceTree = ""; }; - 146695ED1A2729860070D41D /* CON_console.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CON_console.c; sourceTree = ""; }; 1466960C1A2729860070D41D /* iff15bpp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iff15bpp.c; sourceTree = ""; }; 1466960D1A2729860070D41D /* iff8bpp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iff8bpp.c; sourceTree = ""; }; 1466960E1A2729860070D41D /* iffmike.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iffmike.c; sourceTree = ""; }; @@ -436,7 +434,6 @@ 146696181A2729860070D41D /* cfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cfile.h; sourceTree = ""; }; 146696191A2729860070D41D /* checker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = checker.h; sourceTree = ""; }; 1466961A1A2729860070D41D /* cmd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmd.h; sourceTree = ""; }; - 1466961B1A2729860070D41D /* CON_console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CON_console.h; sourceTree = ""; }; 1466961C1A2729860070D41D /* console.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = console.h; sourceTree = ""; }; 1466961D1A2729860070D41D /* d1x.xpm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = d1x.xpm; sourceTree = ""; }; 1466961E1A2729860070D41D /* descent.xpm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = descent.xpm; sourceTree = ""; }; @@ -928,7 +925,6 @@ 146694D01A2729860070D41D /* 2d */, 146694ED1A2729860070D41D /* 3d */, 146694FC1A2729860070D41D /* arch */, - 146695EC1A2729860070D41D /* console */, 1466960A1A2729860070D41D /* iff */, 146696141A2729860070D41D /* include */, 146696471A2729870070D41D /* libmve */, @@ -1430,14 +1426,6 @@ path = include; sourceTree = ""; }; - 146695EC1A2729860070D41D /* console */ = { - isa = PBXGroup; - children = ( - 146695ED1A2729860070D41D /* CON_console.c */, - ); - path = console; - sourceTree = ""; - }; 1466960A1A2729860070D41D /* iff */ = { isa = PBXGroup; children = ( @@ -1468,7 +1456,6 @@ 146696181A2729860070D41D /* cfile.h */, 146696191A2729860070D41D /* checker.h */, 1466961A1A2729860070D41D /* cmd.h */, - 1466961B1A2729860070D41D /* CON_console.h */, 1466961C1A2729860070D41D /* console.h */, 1466961D1A2729860070D41D /* d1x.xpm */, 1466961E1A2729860070D41D /* descent.xpm */, @@ -2292,7 +2279,6 @@ 146698F41A2729870070D41D /* ntmap.c in Sources */, 146698971A2729870070D41D /* gamerend.c in Sources */, 146698611A2729870070D41D /* crypt.c in Sources */, - 146698291A2729870070D41D /* CON_console.c in Sources */, 146698AF1A2729870070D41D /* multibot.c in Sources */, 1466978D1A2729870070D41D /* interp.c in Sources */, 146698B01A2729870070D41D /* netmisc.c in Sources */, diff --git a/include/CON_console.h b/include/CON_console.h deleted file mode 100644 index db6050cf..00000000 --- a/include/CON_console.h +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef CON_console_H -#define CON_console_H - -/*! \mainpage - -\section intro Introduction -SDL_Console is a console that can be added to any SDL application. It is similar to Quake and other games consoles. -A console is meant to be a very simple way of interacting with a program and executing commands. You can also have -more than one console at a time. - -\section docs Documentation -For a detailed description of all functions see \ref CON_console.h. Remark that functions that have the mark "Internal" -are only used internally. There's not much use of calling these functions. - -Have Fun! - -\author Garett Banuk (Original Version) -\author Clemens Wacha (Version 2.x, Documentation) -\author Boris Lesner (Package Maintainer) -\author Bradley Bell (Descent Version) -*/ - - -#include "gr.h" -#include "key.h" - -//! Cut the buffer line if it becomes longer than this -#define CON_CHARS_PER_LINE 128 -//! Cursor blink frequency in ms -#define CON_BLINK_RATE 500 -//! Border in pixels from the most left to the first letter -#define CON_CHAR_BORDER 4 -//! Spacing in pixels between lines -#define CON_LINE_SPACE 1 -//! Default prompt used at the commandline -#define CON_DEFAULT_PROMPT "]" -//! Scroll this many lines at a time (when pressing PGUP or PGDOWN) -#define CON_LINE_SCROLL 2 -//! Indicator showing that you scrolled up the history -#define CON_SCROLL_INDICATOR "^" -//! Cursor shown if we are in insert mode -#define CON_INS_CURSOR "_" -//! Cursor shown if we are in overwrite mode -#define CON_OVR_CURSOR "|" -//! Defines the default hide key (Hide() the console if pressed) -#define CON_DEFAULT_HIDEKEY KEY_ESC -//! Defines the opening/closing speed -#define CON_OPENCLOSE_SPEED 50 - -#ifdef __cplusplus -extern "C" { -#endif - - enum { - CON_CLOSED, //! The console is closed (and not shown) - CON_CLOSING, //! The console is still open and visible but closing - CON_OPENING, //! The console is visible and opening but not yet fully open - CON_OPEN //! The console is open and visible - }; - - /*! This is a struct for each consoles data */ - typedef struct console_information_td { - int Visible; //! enum that tells which visible state we are in CON_HIDE, CON_SHOW, CON_RAISE, CON_LOWER - int RaiseOffset; //! Offset used when scrolling in the console - int HideKey; //! the key that can hide the console - char **ConsoleLines; //! List of all the past lines - char **CommandLines; //! List of all the past commands - int TotalConsoleLines; //! Total number of lines in the console - int ConsoleScrollBack; //! How much the user scrolled back in the console - int TotalCommands; //! Number of commands in the Back Commands - int LineBuffer; //! The number of visible lines in the console (autocalculated) - int VChars; //! The number of visible characters in one console line (autocalculated) - char* Prompt; //! Prompt displayed in command line - char Command[CON_CHARS_PER_LINE]; //! current command in command line = lcommand + rcommand - char RCommand[CON_CHARS_PER_LINE]; //! left hand side of cursor - char LCommand[CON_CHARS_PER_LINE]; //! right hand side of cursor - char VCommand[CON_CHARS_PER_LINE]; //! current visible command line - int CursorPos; //! Current cursor position in CurrentCommand - int Offset; //! CommandOffset (first visible char of command) - if command is too long to fit into console - int InsMode; //! Insert or Overwrite characters? - grs_canvas *ConsoleSurface; //! Canvas of the console - grs_screen *OutputScreen; //! This is the screen to draw the console to - grs_bitmap *BackgroundImage; //! Background image for the console - grs_bitmap *InputBackground; //! Dirty rectangle to draw over behind the users background - int DispX, DispY; //! The top left x and y coords of the console on the display screen -#if 0 - unsigned char ConsoleAlpha; //! The consoles alpha level -#endif - int CommandScrollBack; //! How much the users scrolled back in the command lines - void(*CmdFunction)(struct console_information_td *console, char* command); //! The Function that is executed if you press in the console - char*(*TabFunction)(char* command); //! The Function that is executed if you press in the console - void(*HideFunction)(void); //! The Function that is executed when the console is hidden - } - ConsoleInformation; - - /*! Takes keys from the keyboard and inputs them to the console if the console isVisible(). - If the event was not handled (i.e. WM events or unknown ctrl- or alt-sequences) - the function returns the event for further processing. */ - int CON_Events(int event); - /*! Makes the console visible */ - void CON_Show(ConsoleInformation *console); - /*! Hides the console */ - void CON_Hide(ConsoleInformation *console); - /*! Returns 1 if the console is visible, 0 else */ - int CON_isVisible(ConsoleInformation *console); - /*! Internal: Updates visible state. Used in CON_DrawConsole() */ - void CON_UpdateOffset(ConsoleInformation* console); - /*! Draws the console to the screen if it isVisible()*/ - void CON_DrawConsole(ConsoleInformation *console); - /*! Initializes a new console */ - ConsoleInformation *CON_Init(grs_font *Font, grs_screen *DisplayScreen, int lines, int x, int y, int w, int h); - /*! Calls CON_Free */ - void CON_Destroy(ConsoleInformation *console); - /*! Frees all the memory loaded by the console */ - void CON_Free(ConsoleInformation *console); - /*! printf for the console */ - void CON_Out(ConsoleInformation *console, const char *str, ...); -#if 0 - /*! Sets the alpha channel of an SDL_Surface to the specified value (0 - transparend, - 255 - opaque). Use this function also for OpenGL. */ - void CON_Alpha(ConsoleInformation *console, unsigned char alpha); - /*! Internal: Sets the alpha channel of an SDL_Surface to the specified value. - Preconditions: the surface in question is RGBA. 0 <= a <= 255, where 0 is transparent and 255 opaque */ - void CON_AlphaGL(SDL_Surface *s, int alpha); - /*! Sets a background image for the console */ -#endif - int CON_Background(ConsoleInformation *console, grs_bitmap *image); - /*! Sets font info for the console */ - void CON_Font(ConsoleInformation *console, grs_font *font, int fg, int bg); - /*! Changes current position of the console */ - void CON_Position(ConsoleInformation *console, int x, int y); - /*! Changes the size of the console */ - int CON_Resize(ConsoleInformation *console, int x, int y, int w, int h); - /*! Beams a console to another screen surface. Needed if you want to make a Video restart in your program. This - function first changes the OutputScreen Pointer then calls CON_Resize to adjust the new size. */ - int CON_Transfer(ConsoleInformation* console, grs_screen* new_outputscreen, int x, int y, int w, int h); - /*! Give focus to a console. Make it the "topmost" console. This console will receive events - sent with CON_Events() */ - void CON_Topmost(ConsoleInformation *console); - /*! Modify the prompt of the console */ - void CON_SetPrompt(ConsoleInformation *console, char* newprompt); - /*! Set the key, that invokes a CON_Hide() after press. default is ESCAPE and you can always hide using - ESCAPE and the HideKey. compared against event->key.keysym.sym !! */ - void CON_SetHideKey(ConsoleInformation *console, int key); - /*! Internal: executes the command typed in at the console (called if you press ENTER)*/ - void CON_SetHideFunction(ConsoleInformation *console, void(*HideFunction)(void)); - /*! Sets the callback function that is called after a console has been hidden */ - void CON_Execute(ConsoleInformation *console, char* command); - /*! Sets the callback function that is called if a command was typed in. The function could look like this: - void my_command_handler(ConsoleInformation* console, char* command). @param console: the console the command - came from. @param command: the command string that was typed in. */ - void CON_SetExecuteFunction(ConsoleInformation *console, void(*CmdFunction)(ConsoleInformation *console2, char* command)); - /*! Sets the callback tabulator completion function. char* my_tabcompletion(char* command). If Tab is - pressed, the function gets called with the already typed in command. my_tabcompletion then checks if if can - complete the command or if it should display a list of all matching commands (with CON_Out()). Returns the - completed command or NULL if no completion was made. */ - void CON_SetTabCompletion(ConsoleInformation *console, char*(*TabFunction)(char* command)); - /*! Internal: Gets called when TAB was pressed */ - void CON_TabCompletion(ConsoleInformation *console); - /*! Internal: makes newline (same as printf("\n") or CON_Out(console, "\n") ) */ - void CON_NewLineConsole(ConsoleInformation *console); - /*! Internal: shift command history (the one you can switch with the up/down keys) */ - void CON_NewLineCommand(ConsoleInformation *console); - /*! Internal: updates console after resize etc. */ - void CON_UpdateConsole(ConsoleInformation *console); - - - /*! Internal: Default Execute callback */ - void Default_CmdFunction(ConsoleInformation *console, char* command); - /*! Internal: Default TabCompletion callback */ - char* Default_TabFunction(char* command); - /*! Internal: Default Hide callback */ - void Default_HideFunction(void); - - /*! Internal: draws the commandline the user is typing in to the screen. called by update? */ - void DrawCommandLine(); - - /*! Internal: Gets called if you press the LEFT key (move cursor left) */ - void Cursor_Left(ConsoleInformation *console); - /*! Internal: Gets called if you press the RIGHT key (move cursor right) */ - void Cursor_Right(ConsoleInformation *console); - /*! Internal: Gets called if you press the HOME key (move cursor to the beginning - of the line */ - void Cursor_Home(ConsoleInformation *console); - /*! Internal: Gets called if you press the END key (move cursor to the end of the line*/ - void Cursor_End(ConsoleInformation *console); - /*! Internal: Called if you press DELETE (deletes character under the cursor) */ - void Cursor_Del(ConsoleInformation *console); - /*! Internal: Called if you press BACKSPACE (deletes character left of cursor) */ - void Cursor_BSpace(ConsoleInformation *console); - /*! Internal: Called if you type in a character (add the char to the command) */ - void Cursor_Add(ConsoleInformation *console, int event); - - /*! Internal: Called if you press Ctrl-C (deletes the commandline) */ - void Clear_Command(ConsoleInformation *console); - /*! Internal: Called if you press Ctrl-L (deletes the History) */ - void Clear_History(ConsoleInformation *console); - - /*! Internal: Called if you press UP key (switches through recent typed in commands */ - void Command_Up(ConsoleInformation *console); - /*! Internal: Called if you press DOWN key (switches through recent typed in commands */ - void Command_Down(ConsoleInformation *console); - -#ifdef __cplusplus -}; -#endif - -#endif - - diff --git a/include/console.h b/include/console.h index d3f9c773..cb0f2f2c 100644 --- a/include/console.h +++ b/include/console.h @@ -1,10 +1,117 @@ -/* Console */ +/* Console, based on an old version of SDL_Console */ #ifndef _CONSOLE_H_ #define _CONSOLE_H_ 1 +/*! \mainpage + + \section intro Introduction + SDL_Console is a console that can be added to any SDL application. It is similar to Quake and other games consoles. + A console is meant to be a very simple way of interacting with a program and executing commands. You can also have + more than one console at a time. + + \section docs Documentation + For a detailed description of all functions see \ref CON_console.h. Remark that functions that have the mark "Internal" + are only used internally. There's not much use of calling these functions. + + Have Fun! + + \author Garett Banuk (Original Version) + \author Clemens Wacha (Version 2.x, Documentation) + \author Boris Lesner (Package Maintainer) + \author Bradley Bell (Descent Version) + */ + + #include "cmd.h" #include "cvar.h" +#include "gr.h" +#include "key.h" + +//! Cut the buffer line if it becomes longer than this +#define CON_CHARS_PER_LINE 128 +//! Cursor blink frequency in ms +#define CON_BLINK_RATE 500 +//! Border in pixels from the most left to the first letter +#define CON_CHAR_BORDER 4 +//! Spacing in pixels between lines +#define CON_LINE_SPACE 1 +//! Default prompt used at the commandline +#define CON_DEFAULT_PROMPT "]" +//! Scroll this many lines at a time (when pressing PGUP or PGDOWN) +#define CON_LINE_SCROLL 2 +//! Indicator showing that you scrolled up the history +#define CON_SCROLL_INDICATOR "^" +//! Cursor shown if we are in insert mode +#define CON_INS_CURSOR "_" +//! Cursor shown if we are in overwrite mode +#define CON_OVR_CURSOR "|" +//! Defines the default hide key (Hide() the console if pressed) +#define CON_DEFAULT_HIDEKEY KEY_ESC +//! Defines the opening/closing speed +#define CON_OPENCLOSE_SPEED 50 + +enum { + CON_CLOSED, //! The console is closed (and not shown) + CON_CLOSING, //! The console is still open and visible but closing + CON_OPENING, //! The console is visible and opening but not yet fully open + CON_OPEN //! The console is open and visible +}; + +/*! This is a struct for each consoles data */ +typedef struct console_information_td { + int Visible; //! enum that tells which visible state we are in CON_HIDE, CON_SHOW, CON_RAISE, CON_LOWER + int RaiseOffset; //! Offset used when scrolling in the console + int HideKey; //! the key that can hide the console + char **ConsoleLines; //! List of all the past lines + char **CommandLines; //! List of all the past commands + int TotalConsoleLines; //! Total number of lines in the console + int ConsoleScrollBack; //! How much the user scrolled back in the console + int TotalCommands; //! Number of commands in the Back Commands + int LineBuffer; //! The number of visible lines in the console (autocalculated) + int VChars; //! The number of visible characters in one console line (autocalculated) + char* Prompt; //! Prompt displayed in command line + char Command[CON_CHARS_PER_LINE]; //! current command in command line = lcommand + rcommand + char RCommand[CON_CHARS_PER_LINE]; //! left hand side of cursor + char LCommand[CON_CHARS_PER_LINE]; //! right hand side of cursor + char VCommand[CON_CHARS_PER_LINE]; //! current visible command line + int CursorPos; //! Current cursor position in CurrentCommand + int Offset; //! CommandOffset (first visible char of command) - if command is too long to fit into console + int InsMode; //! Insert or Overwrite characters? + grs_canvas *ConsoleSurface; //! Canvas of the console + grs_screen *OutputScreen; //! This is the screen to draw the console to + grs_bitmap *BackgroundImage; //! Background image for the console + grs_bitmap *InputBackground; //! Dirty rectangle to draw over behind the users background + int DispX, DispY; //! The top left x and y coords of the console on the display screen +#if 0 + unsigned char ConsoleAlpha; //! The consoles alpha level +#endif + int CommandScrollBack; //! How much the users scrolled back in the command lines + void(*CmdFunction)(struct console_information_td *console, char* command); //! The Function that is executed if you press in the console + char*(*TabFunction)(char* command); //! The Function that is executed if you press in the console + void(*HideFunction)(void); //! The Function that is executed when the console is hidden +} +ConsoleInformation; + +/*! Takes keys from the keyboard and inputs them to the console if the console isVisible(). + If the event was not handled (i.e. WM events or unknown ctrl- or alt-sequences) + the function returns the event for further processing. */ +int CON_Events(int event); +/*! Makes the console visible */ +void CON_Show(ConsoleInformation *console); +/*! Hides the console */ +void CON_Hide(ConsoleInformation *console); +/*! Returns 1 if the console is visible, 0 else */ +int CON_isVisible(ConsoleInformation *console); +/*! Draws the console to the screen if it isVisible()*/ +void CON_DrawConsole(ConsoleInformation *console); +/*! Initializes a new console */ +ConsoleInformation *CON_Init(grs_font *Font, grs_screen *DisplayScreen, int lines, int x, int y, int w, int h); +/*! printf for the console */ +void CON_Out(ConsoleInformation *console, const char *str, ...); +/*! Changes the size of the console */ +int CON_Resize(ConsoleInformation *console, int x, int y, int w, int h); + /* Priority levels */ #define CON_CRITICAL -2 diff --git a/main/console.c b/main/console.c index c710d32a..a4a0dc25 100644 --- a/main/console.c +++ b/main/console.c @@ -1,15 +1,1207 @@ -/* $Id: console.c,v 1.18 2003-11-26 12:39:00 btb Exp $ */ /* - * * Code for controlling the console + * Based on an old version of SDL_Console * + * Written By: Garrett Banuk + * Code Cleanup and heavily extended by: Clemens Wacha + * Ported to use native Descent interfaces by: Bradley Bell * + * This is free, just be sure to give us credit when using it + * in any of your programs. */ #ifdef HAVE_CONFIG_H #include #endif +#include +#include +#include +#include + +#include "console.h" +#include "u_mem.h" +#include "gr.h" +#include "timer.h" + + +#define FG_COLOR grd_curcanv->cv_font_fg_color +#define get_msecs() approx_fsec_to_msec(timer_get_approx_seconds()) + + +/* This contains a pointer to the "topmost" console. The console that + * is currently taking keyboard input. */ +static ConsoleInformation *Topmost; + +/* Internals */ +void CON_UpdateOffset(ConsoleInformation* console); +/*! Calls CON_Free */ +void CON_Destroy(ConsoleInformation *console); +/*! Frees all the memory loaded by the console */ +void CON_Free(ConsoleInformation *console); +#if 0 +/*! Sets the alpha channel of an SDL_Surface to the specified value (0 - transparend, + 255 - opaque). Use this function also for OpenGL. */ +void CON_Alpha(ConsoleInformation *console, unsigned char alpha); +/*! Internal: Sets the alpha channel of an SDL_Surface to the specified value. + Preconditions: the surface in question is RGBA. 0 <= a <= 255, where 0 is transparent and 255 opaque */ +void CON_AlphaGL(SDL_Surface *s, int alpha); +/*! Sets a background image for the console */ +#endif +int CON_Background(ConsoleInformation *console, grs_bitmap *image); +/*! Sets font info for the console */ +void CON_Font(ConsoleInformation *console, grs_font *font, int fg, int bg); +/*! Changes current position of the console */ +void CON_Position(ConsoleInformation *console, int x, int y); +/*! Beams a console to another screen surface. Needed if you want to make a Video restart in your program. This + function first changes the OutputScreen Pointer then calls CON_Resize to adjust the new size. */ +int CON_Transfer(ConsoleInformation* console, grs_screen* new_outputscreen, int x, int y, int w, int h); +/*! Give focus to a console. Make it the "topmost" console. This console will receive events + sent with CON_Events() */ +void CON_Topmost(ConsoleInformation *console); +/*! Modify the prompt of the console */ +void CON_SetPrompt(ConsoleInformation *console, char* newprompt); +/*! Set the key, that invokes a CON_Hide() after press. default is ESCAPE and you can always hide using + ESCAPE and the HideKey. compared against event->key.keysym.sym !! */ +void CON_SetHideKey(ConsoleInformation *console, int key); +/*! Internal: executes the command typed in at the console (called if you press ENTER)*/ +void CON_SetHideFunction(ConsoleInformation *console, void(*HideFunction)(void)); +/*! Sets the callback function that is called after a console has been hidden */ +void CON_Execute(ConsoleInformation *console, char* command); +/*! Sets the callback function that is called if a command was typed in. The function could look like this: + void my_command_handler(ConsoleInformation* console, char* command). @param console: the console the command + came from. @param command: the command string that was typed in. */ +void CON_SetExecuteFunction(ConsoleInformation *console, void(*CmdFunction)(ConsoleInformation *console2, char* command)); +/*! Sets the callback tabulator completion function. char* my_tabcompletion(char* command). If Tab is + pressed, the function gets called with the already typed in command. my_tabcompletion then checks if if can + complete the command or if it should display a list of all matching commands (with CON_Out()). Returns the + completed command or NULL if no completion was made. */ +void CON_SetTabCompletion(ConsoleInformation *console, char*(*TabFunction)(char* command)); +/*! Internal: Gets called when TAB was pressed */ +void CON_TabCompletion(ConsoleInformation *console); +/*! Internal: makes newline (same as printf("\n") or CON_Out(console, "\n") ) */ +void CON_NewLineConsole(ConsoleInformation *console); +/*! Internal: shift command history (the one you can switch with the up/down keys) */ +void CON_NewLineCommand(ConsoleInformation *console); +/*! Internal: updates console after resize etc. */ +void CON_UpdateConsole(ConsoleInformation *console); + + +/*! Internal: Default Execute callback */ +void Default_CmdFunction(ConsoleInformation *console, char* command); +/*! Internal: Default TabCompletion callback */ +char* Default_TabFunction(char* command); +/*! Internal: Default Hide callback */ +void Default_HideFunction(void); + +/*! Internal: draws the commandline the user is typing in to the screen. called by update? */ +void DrawCommandLine(); + +/*! Internal: Gets called if you press the LEFT key (move cursor left) */ +void Cursor_Left(ConsoleInformation *console); +/*! Internal: Gets called if you press the RIGHT key (move cursor right) */ +void Cursor_Right(ConsoleInformation *console); +/*! Internal: Gets called if you press the HOME key (move cursor to the beginning + of the line */ +void Cursor_Home(ConsoleInformation *console); +/*! Internal: Gets called if you press the END key (move cursor to the end of the line*/ +void Cursor_End(ConsoleInformation *console); +/*! Internal: Called if you press DELETE (deletes character under the cursor) */ +void Cursor_Del(ConsoleInformation *console); +/*! Internal: Called if you press BACKSPACE (deletes character left of cursor) */ +void Cursor_BSpace(ConsoleInformation *console); +/*! Internal: Called if you type in a character (add the char to the command) */ +void Cursor_Add(ConsoleInformation *console, int event); + +/*! Internal: Called if you press Ctrl-C (deletes the commandline) */ +void Clear_Command(ConsoleInformation *console); +/*! Internal: Called if you press Ctrl-L (deletes the History) */ +void Clear_History(ConsoleInformation *console); + +/*! Internal: Called if you press UP key (switches through recent typed in commands */ +void Command_Up(ConsoleInformation *console); +/*! Internal: Called if you press DOWN key (switches through recent typed in commands */ +void Command_Down(ConsoleInformation *console); + + +/* Takes keys from the keyboard and inputs them to the console + If the event was not handled (i.e. WM events or unknown ctrl-shift + sequences) the function returns the event for further processing. */ +int CON_Events(int event) +{ + if(Topmost == NULL) + return event; + if(!CON_isVisible(Topmost)) + return event; + + if(event & KEY_CTRLED) + { + //CTRL pressed + switch(event & ~KEY_CTRLED) + { + case KEY_A: + Cursor_Home(Topmost); + break; + case KEY_E: + Cursor_End(Topmost); + break; + case KEY_C: + Clear_Command(Topmost); + break; + case KEY_L: + Clear_History(Topmost); + CON_UpdateConsole(Topmost); + break; + default: + return event; + } + } + else if(event & KEY_ALTED) + { + //the console does not handle ALT combinations! + return event; + } + else + { + //first of all, check if the console hide key was pressed + if(event == Topmost->HideKey) + { + CON_Hide(Topmost); + return 0; + } + switch (event & 0xff) + { + case KEY_LSHIFT: + case KEY_RSHIFT: + return event; + case KEY_HOME: + if(event & KEY_SHIFTED) + { + Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; + CON_UpdateConsole(Topmost); + } else { + Cursor_Home(Topmost); + } + break; + case KEY_END: + if(event & KEY_SHIFTED) + { + Topmost->ConsoleScrollBack = 0; + CON_UpdateConsole(Topmost); + } else { + Cursor_End(Topmost); + } + break; + case KEY_PAGEUP: + Topmost->ConsoleScrollBack += CON_LINE_SCROLL; + if(Topmost->ConsoleScrollBack > Topmost->LineBuffer-1) + Topmost->ConsoleScrollBack = Topmost->LineBuffer-1; + + CON_UpdateConsole(Topmost); + break; + case KEY_PAGEDOWN: + Topmost->ConsoleScrollBack -= CON_LINE_SCROLL; + if(Topmost->ConsoleScrollBack < 0) + Topmost->ConsoleScrollBack = 0; + CON_UpdateConsole(Topmost); + break; + case KEY_UP: + Command_Up(Topmost); + break; + case KEY_DOWN: + Command_Down(Topmost); + break; + case KEY_LEFT: + Cursor_Left(Topmost); + break; + case KEY_RIGHT: + Cursor_Right(Topmost); + break; + case KEY_BACKSP: + Cursor_BSpace(Topmost); + break; + case KEY_DELETE: + Cursor_Del(Topmost); + break; + case KEY_INSERT: + Topmost->InsMode = 1-Topmost->InsMode; + break; + case KEY_TAB: + CON_TabCompletion(Topmost); + break; + case KEY_ENTER: + if(strlen(Topmost->Command) > 0) { + CON_NewLineCommand(Topmost); + + // copy the input into the past commands strings + strcpy(Topmost->CommandLines[0], Topmost->Command); + + // display the command including the prompt + CON_Out(Topmost, "%s%s", Topmost->Prompt, Topmost->Command); + CON_UpdateConsole(Topmost); + + CON_Execute(Topmost, Topmost->Command); + //printf("Command: %s\n", Topmost->Command); + + Clear_Command(Topmost); + Topmost->CommandScrollBack = -1; + } + break; + case KEY_LAPOSTRO: + //deactivate Console + CON_Hide(Topmost); + return 0; + default: + if (key_to_ascii(event) == 255) + break; + if(Topmost->InsMode) + Cursor_Add(Topmost, event); + else { + Cursor_Add(Topmost, event); + Cursor_Del(Topmost); + } + } + } + return 0; +} + +#if 0 +/* CON_AlphaGL() -- sets the alpha channel of an SDL_Surface to the + * specified value. Preconditions: the surface in question is RGBA. + * 0 <= a <= 255, where 0 is transparent and 255 is opaque. */ +void CON_AlphaGL(SDL_Surface *s, int alpha) { + Uint8 val; + int x, y, w, h; + Uint32 pixel; + Uint8 r, g, b, a; + SDL_PixelFormat *format; + static char errorPrinted = 0; + + + /* debugging assertions -- these slow you down, but hey, crashing sucks */ + if(!s) { + PRINT_ERROR("NULL Surface passed to CON_AlphaGL\n"); + return; + } + + /* clamp alpha value to 0...255 */ + if(alpha < SDL_ALPHA_TRANSPARENT) + val = SDL_ALPHA_TRANSPARENT; + else if(alpha > SDL_ALPHA_OPAQUE) + val = SDL_ALPHA_OPAQUE; + else + val = alpha; + + /* loop over alpha channels of each pixel, setting them appropriately. */ + w = s->w; + h = s->h; + format = s->format; + switch (format->BytesPerPixel) { + case 2: + /* 16-bit surfaces don't seem to support alpha channels. */ + if(!errorPrinted) { + errorPrinted = 1; + PRINT_ERROR("16-bit SDL surfaces do not support alpha-blending under OpenGL.\n"); + } + break; + case 4: { + /* we can do this very quickly in 32-bit mode. 24-bit is more + * difficult. And since 24-bit mode is reall the same as 32-bit, + * so it usually ends up taking this route too. Win! Unroll loop + * and use pointer arithmetic for extra speed. */ + int numpixels = h * (w << 2); + Uint8 *pix = (Uint8 *) (s->pixels); + Uint8 *last = pix + numpixels; + Uint8 *pixel; + if((numpixels & 0x7) == 0) + for(pixel = pix + 3; pixel < last; pixel += 32) + *pixel = *(pixel + 4) = *(pixel + 8) = *(pixel + 12) = *(pixel + 16) = *(pixel + 20) = *(pixel + 24) = *(pixel + 28) = val; + else + for(pixel = pix + 3; pixel < last; pixel += 4) + *pixel = val; + break; + } + default: + /* we have no choice but to do this slowly. */ + for(y = 0; y < h; ++y) + for(x = 0; x < w; ++x) { + char print = 0; + /* Lock the surface for direct access to the pixels */ + if(SDL_MUSTLOCK(s) && SDL_LockSurface(s) < 0) { + PRINT_ERROR("Can't lock surface: "); + fprintf(stderr, "%s\n", SDL_GetError()); + return; + } + pixel = DT_GetPixel(s, x, y); + if(x == 0 && y == 0) + print = 1; + SDL_GetRGBA(pixel, format, &r, &g, &b, &a); + pixel = SDL_MapRGBA(format, r, g, b, val); + SDL_GetRGBA(pixel, format, &r, &g, &b, &a); + DT_PutPixel(s, x, y, pixel); + + /* unlock surface again */ + if(SDL_MUSTLOCK(s)) + SDL_UnlockSurface(s); + } + break; + } +} +#endif + + +/* Updates the console buffer */ +void CON_UpdateConsole(ConsoleInformation *console) { + int loop; + int loop2; + int Screenlines; + grs_canvas *canv_save; + short orig_color; + + if(!console) + return; + + /* Due to the Blits, the update is not very fast: So only update if it's worth it */ + if(!CON_isVisible(console)) + return; + + Screenlines = console->ConsoleSurface->cv_h / (CON_LINE_SPACE + console->ConsoleSurface->cv_font->ft_h); + + canv_save = grd_curcanv; + gr_set_current_canvas(console->ConsoleSurface); + +#if 0 + SDL_FillRect(console->ConsoleSurface, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, console->ConsoleAlpha)); +#else + //gr_rect(0,0, +#endif + +#if 0 + if(console->OutputScreen->flags & SDL_OPENGLBLIT) + SDL_SetAlpha(console->ConsoleSurface, 0, SDL_ALPHA_OPAQUE); +#endif + + /* draw the background image if there is one */ + if(console->BackgroundImage) + gr_bitmap(0, 0, console->BackgroundImage); + + /* Draw the text from the back buffers, calculate in the scrollback from the user + * this is a normal SDL software-mode blit, so we need to temporarily set the ColorKey + * for the font, and then clear it when we're done. + */ +#if 0 + if((console->OutputScreen->flags & SDL_OPENGLBLIT) && (console->OutputScreen->format->BytesPerPixel > 2)) { + Uint32 *pix = (Uint32 *) (CurrentFont->FontSurface->pixels); + SDL_SetColorKey(CurrentFont->FontSurface, SDL_SRCCOLORKEY, *pix); + } +#endif + + //now draw text from last but second line to top + for(loop = 0; loop < Screenlines-1 && loop < console->LineBuffer - console->ConsoleScrollBack; loop++) { + if(console->ConsoleScrollBack != 0 && loop == 0) + for(loop2 = 0; loop2 < (console->VChars / 5) + 1; loop2++) + { + orig_color = FG_COLOR; + gr_string(CON_CHAR_BORDER + (loop2*5*console->ConsoleSurface->cv_font->ft_w), (Screenlines - loop - 2) * (CON_LINE_SPACE + console->ConsoleSurface->cv_font->ft_h), CON_SCROLL_INDICATOR); + FG_COLOR = orig_color; + } + else + { + orig_color = FG_COLOR; + gr_string(CON_CHAR_BORDER, (Screenlines - loop - 2) * (CON_LINE_SPACE + console->ConsoleSurface->cv_font->ft_h), console->ConsoleLines[console->ConsoleScrollBack + loop]); + FG_COLOR = orig_color; + } + } + + gr_set_current_canvas(canv_save); + +#if 0 + if(console->OutputScreen->flags & SDL_OPENGLBLIT) + SDL_SetColorKey(CurrentFont->FontSurface, 0, 0); +#endif +} + +void CON_UpdateOffset(ConsoleInformation* console) { + if(!console) + return; + + switch(console->Visible) { + case CON_CLOSING: + console->RaiseOffset -= CON_OPENCLOSE_SPEED; + if(console->RaiseOffset <= 0) { + console->RaiseOffset = 0; + console->Visible = CON_CLOSED; + } + break; + case CON_OPENING: + console->RaiseOffset += CON_OPENCLOSE_SPEED; + if(console->RaiseOffset >= console->ConsoleSurface->cv_h) { + console->RaiseOffset = console->ConsoleSurface->cv_h; + console->Visible = CON_OPEN; + } + break; + case CON_OPEN: + case CON_CLOSED: + break; + } +} + +/* Draws the console buffer to the screen if the console is "visible" */ +void CON_DrawConsole(ConsoleInformation *console) { + grs_canvas *canv_save; + grs_bitmap *clip; + + if(!console) + return; + + /* only draw if console is visible: here this means, that the console is not CON_CLOSED */ + if(console->Visible == CON_CLOSED) + return; + + /* Update the scrolling offset */ + CON_UpdateOffset(console); + + /* Update the command line since it has a blinking cursor */ + DrawCommandLine(); + +#if 0 + /* before drawing, make sure the alpha channel of the console surface is set + * properly. (sigh) I wish we didn't have to do this every frame... */ + if(console->OutputScreen->flags & SDL_OPENGLBLIT) + CON_AlphaGL(console->ConsoleSurface, console->ConsoleAlpha); +#endif + + canv_save = grd_curcanv; + gr_set_current_canvas(&console->OutputScreen->sc_canvas); + + clip = gr_create_sub_bitmap(&console->ConsoleSurface->cv_bitmap, 0, console->ConsoleSurface->cv_h - console->RaiseOffset, console->ConsoleSurface->cv_w, console->RaiseOffset); + + gr_bitmap(console->DispX, console->DispY, clip); + gr_free_sub_bitmap(clip); + +#if 0 + if(console->OutputScreen->flags & SDL_OPENGLBLIT) + SDL_UpdateRects(console->OutputScreen, 1, &DestRect); +#endif + + gr_set_current_canvas(canv_save); +} + + +/* Initializes the console */ +ConsoleInformation *CON_Init(grs_font *Font, grs_screen *DisplayScreen, int lines, int x, int y, int w, int h) +{ + int loop; + ConsoleInformation *newinfo; + + + /* Create a new console struct and init it. */ + if((newinfo = (ConsoleInformation *) d_malloc(sizeof(ConsoleInformation))) == NULL) { + //PRINT_ERROR("Could not allocate the space for a new console info struct.\n"); + return NULL; + } + newinfo->Visible = CON_CLOSED; + newinfo->RaiseOffset = 0; + newinfo->ConsoleLines = NULL; + newinfo->CommandLines = NULL; + newinfo->TotalConsoleLines = 0; + newinfo->ConsoleScrollBack = 0; + newinfo->TotalCommands = 0; + newinfo->BackgroundImage = NULL; +#if 0 + newinfo->ConsoleAlpha = SDL_ALPHA_OPAQUE; +#endif + newinfo->Offset = 0; + newinfo->InsMode = 1; + newinfo->CursorPos = 0; + newinfo->CommandScrollBack = 0; + newinfo->OutputScreen = DisplayScreen; + newinfo->Prompt = CON_DEFAULT_PROMPT; + newinfo->HideKey = CON_DEFAULT_HIDEKEY; + + CON_SetExecuteFunction(newinfo, Default_CmdFunction); + CON_SetTabCompletion(newinfo, Default_TabFunction); + CON_SetHideFunction(newinfo, Default_HideFunction); + + /* make sure that the size of the console is valid */ + if(w > newinfo->OutputScreen->sc_w || w < Font->ft_w * 32) + w = newinfo->OutputScreen->sc_w; + if(h > newinfo->OutputScreen->sc_h || h < Font->ft_h) + h = newinfo->OutputScreen->sc_h; + if(x < 0 || x > newinfo->OutputScreen->sc_w - w) + newinfo->DispX = 0; + else + newinfo->DispX = x; + if(y < 0 || y > newinfo->OutputScreen->sc_h - h) + newinfo->DispY = 0; + else + newinfo->DispY = y; + + /* load the console surface */ + newinfo->ConsoleSurface = gr_create_canvas(w, h); + + /* Load the consoles font */ + { + grs_canvas *canv_save; + + canv_save = grd_curcanv; + gr_set_current_canvas(newinfo->ConsoleSurface); + gr_set_curfont(Font); + gr_set_fontcolor(gr_getcolor(63,63,63), -1); + gr_set_current_canvas(canv_save); + } + + + /* Load the dirty rectangle for user input */ + newinfo->InputBackground = gr_create_bitmap(w, newinfo->ConsoleSurface->cv_font->ft_h); +#if 0 + SDL_FillRect(newinfo->InputBackground, NULL, SDL_MapRGBA(newinfo->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); +#endif + + /* calculate the number of visible characters in the command line */ + newinfo->VChars = (w - CON_CHAR_BORDER) / newinfo->ConsoleSurface->cv_font->ft_w; + if(newinfo->VChars > CON_CHARS_PER_LINE) + newinfo->VChars = CON_CHARS_PER_LINE; + + /* We would like to have a minumum # of lines to guarentee we don't create a memory error */ + if(h / (CON_LINE_SPACE + newinfo->ConsoleSurface->cv_font->ft_h) > lines) + newinfo->LineBuffer = h / (CON_LINE_SPACE + newinfo->ConsoleSurface->cv_font->ft_h); + else + newinfo->LineBuffer = lines; + + + newinfo->ConsoleLines = (char **)d_malloc(sizeof(char *) * newinfo->LineBuffer); + newinfo->CommandLines = (char **)d_malloc(sizeof(char *) * newinfo->LineBuffer); + for(loop = 0; loop <= newinfo->LineBuffer - 1; loop++) { + newinfo->ConsoleLines[loop] = (char *)d_calloc(CON_CHARS_PER_LINE, sizeof(char)); + newinfo->CommandLines[loop] = (char *)d_calloc(CON_CHARS_PER_LINE, sizeof(char)); + } + memset(newinfo->Command, 0, CON_CHARS_PER_LINE); + memset(newinfo->LCommand, 0, CON_CHARS_PER_LINE); + memset(newinfo->RCommand, 0, CON_CHARS_PER_LINE); + memset(newinfo->VCommand, 0, CON_CHARS_PER_LINE); + + + CON_Out(newinfo, "Console initialised."); + CON_NewLineConsole(newinfo); + //CON_ListCommands(newinfo); + + return newinfo; +} + +/* Makes the console visible */ +void CON_Show(ConsoleInformation *console) { + if(console) { + console->Visible = CON_OPENING; + CON_UpdateConsole(console); + } +} + +/* Hides the console (make it invisible) */ +void CON_Hide(ConsoleInformation *console) { + if(console) + console->Visible = CON_CLOSING; + console->HideFunction(); +} + +/* tells wether the console is visible or not */ +int CON_isVisible(ConsoleInformation *console) { + if(!console) + return CON_CLOSED; + return((console->Visible == CON_OPEN) || (console->Visible == CON_OPENING)); +} + +/* Frees all the memory loaded by the console */ +void CON_Destroy(ConsoleInformation *console) { + CON_Free(console); +} + +/* Frees all the memory loaded by the console */ +void CON_Free(ConsoleInformation *console) { + int i; + + if(!console) + return; + + //CON_DestroyCommands(); + for(i = 0; i <= console->LineBuffer - 1; i++) { + d_free(console->ConsoleLines[i]); + d_free(console->CommandLines[i]); + } + d_free(console->ConsoleLines); + d_free(console->CommandLines); + + console->ConsoleLines = NULL; + console->CommandLines = NULL; + + gr_free_canvas(console->ConsoleSurface); + console->ConsoleSurface = NULL; + + if (console->BackgroundImage) + gr_free_bitmap(console->BackgroundImage); + console->BackgroundImage = NULL; + + gr_free_bitmap(console->InputBackground); + console->InputBackground = NULL; + + d_free(console); +} + + +/* Increments the console lines */ +void CON_NewLineConsole(ConsoleInformation *console) { + int loop; + char* temp; + + if(!console) + return; + + temp = console->ConsoleLines[console->LineBuffer - 1]; + + for(loop = console->LineBuffer - 1; loop > 0; loop--) + console->ConsoleLines[loop] = console->ConsoleLines[loop - 1]; + + console->ConsoleLines[0] = temp; + + memset(console->ConsoleLines[0], 0, CON_CHARS_PER_LINE); + if(console->TotalConsoleLines < console->LineBuffer - 1) + console->TotalConsoleLines++; + + //Now adjust the ConsoleScrollBack + //dont scroll if not at bottom + if(console->ConsoleScrollBack != 0) + console->ConsoleScrollBack++; + //boundaries + if(console->ConsoleScrollBack > console->LineBuffer-1) + console->ConsoleScrollBack = console->LineBuffer-1; + +} + + +/* Increments the command lines */ +void CON_NewLineCommand(ConsoleInformation *console) { + int loop; + char *temp; + + if(!console) + return; + + temp = console->CommandLines[console->LineBuffer - 1]; + + + for(loop = console->LineBuffer - 1; loop > 0; loop--) + console->CommandLines[loop] = console->CommandLines[loop - 1]; + + console->CommandLines[0] = temp; + + memset(console->CommandLines[0], 0, CON_CHARS_PER_LINE); + if(console->TotalCommands < console->LineBuffer - 1) + console->TotalCommands++; +} + +/* Draws the command line the user is typing in to the screen */ +/* completely rewritten by C.Wacha */ +void DrawCommandLine() { + int x; + int commandbuffer; +#if 0 + grs_font* CurrentFont; +#endif + static unsigned int LastBlinkTime = 0; /* Last time the consoles cursor blinked */ + static int LastCursorPos = 0; // Last Cursor Position + static int Blink = 0; /* Is the cursor currently blinking */ + grs_canvas *canv_save; + short orig_color; + + if(!Topmost) + return; + + commandbuffer = Topmost->VChars - strlen(Topmost->Prompt)-1; // -1 to make cursor visible + +#if 0 + CurrentFont = Topmost->ConsoleSurface->cv_font; +#endif + + //Concatenate the left and right side to command + strcpy(Topmost->Command, Topmost->LCommand); + strncat(Topmost->Command, Topmost->RCommand, strlen(Topmost->RCommand)); + + //calculate display offset from current cursor position + if(Topmost->Offset < Topmost->CursorPos - commandbuffer) + Topmost->Offset = Topmost->CursorPos - commandbuffer; + if(Topmost->Offset > Topmost->CursorPos) + Topmost->Offset = Topmost->CursorPos; + + //first add prompt to visible part + strcpy(Topmost->VCommand, Topmost->Prompt); + + //then add the visible part of the command + strncat(Topmost->VCommand, &Topmost->Command[Topmost->Offset], strlen(&Topmost->Command[Topmost->Offset])); + + //now display the result + +#if 0 + //once again we're drawing text, so in OpenGL context we need to temporarily set up + //software-mode transparency. + if(Topmost->OutputScreen->flags & SDL_OPENGLBLIT) { + Uint32 *pix = (Uint32 *) (CurrentFont->FontSurface->pixels); + SDL_SetColorKey(CurrentFont->FontSurface, SDL_SRCCOLORKEY, *pix); + } +#endif + + canv_save = grd_curcanv; + gr_set_current_canvas(Topmost->ConsoleSurface); + + //first of all restore InputBackground + gr_bitmap(0, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->InputBackground); + + //now add the text + orig_color = FG_COLOR; + gr_string(CON_CHAR_BORDER, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->VCommand); + FG_COLOR = orig_color; + + //at last add the cursor + //check if the blink period is over + if(get_msecs() > LastBlinkTime) { + LastBlinkTime = get_msecs() + CON_BLINK_RATE; + if(Blink) + Blink = 0; + else + Blink = 1; + } + + //check if cursor has moved - if yes display cursor anyway + if(Topmost->CursorPos != LastCursorPos) { + LastCursorPos = Topmost->CursorPos; + LastBlinkTime = get_msecs() + CON_BLINK_RATE; + Blink = 1; + } + + if(Blink) { + int prompt_width, cmd_width, h, w; + + gr_get_string_size(Topmost->Prompt, &prompt_width, &h, &w); + gr_get_string_size(Topmost->LCommand + Topmost->Offset, &cmd_width, &h, &w); + x = CON_CHAR_BORDER + prompt_width + cmd_width; + orig_color = FG_COLOR; + if(Topmost->InsMode) + gr_string(x, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, CON_INS_CURSOR); + else + gr_string(x, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, CON_OVR_CURSOR); + FG_COLOR = orig_color; + } + + gr_set_current_canvas(canv_save); + + +#if 0 + if(Topmost->OutputScreen->flags & SDL_OPENGLBLIT) { + SDL_SetColorKey(CurrentFont->FontSurface, 0, 0); + } +#endif +} + +#ifdef _MSC_VER +# define vsnprintf _vsnprintf +#endif + +/* Outputs text to the console (in game), up to CON_CHARS_PER_LINE chars can be entered */ +void CON_Out(ConsoleInformation *console, const char *str, ...) { + va_list marker; + //keep some space free for stuff like CON_Out(console, "blablabla %s", console->Command); + char temp[CON_CHARS_PER_LINE + 128]; + char* ptemp; + + if(!console) + return; + + va_start(marker, str); + vsnprintf(temp, CON_CHARS_PER_LINE + 127, str, marker); + va_end(marker); + + ptemp = temp; + + //temp now contains the complete string we want to output + // the only problem is that temp is maybe longer than the console + // width so we have to cut it into several pieces + + if(console->ConsoleLines) { + while(strlen(ptemp) > console->VChars) { + CON_NewLineConsole(console); + strncpy(console->ConsoleLines[0], ptemp, console->VChars); + console->ConsoleLines[0][console->VChars] = '\0'; + ptemp = &ptemp[console->VChars]; + } + CON_NewLineConsole(console); + strncpy(console->ConsoleLines[0], ptemp, console->VChars); + console->ConsoleLines[0][console->VChars] = '\0'; + CON_UpdateConsole(console); + } + + /* And print to stdout */ + //printf("%s\n", temp); +} + + +#if 0 +/* Sets the alpha level of the console, 0 turns off alpha blending */ +void CON_Alpha(ConsoleInformation *console, unsigned char alpha) { + if(!console) + return; + + /* store alpha as state! */ + console->ConsoleAlpha = alpha; + + if((console->OutputScreen->flags & SDL_OPENGLBLIT) == 0) { + if(alpha == 0) + SDL_SetAlpha(console->ConsoleSurface, 0, alpha); + else + SDL_SetAlpha(console->ConsoleSurface, SDL_SRCALPHA, alpha); + } + + // CON_UpdateConsole(console); +} +#endif + + +/* Adds background image to the console, scaled to size of console*/ +int CON_Background(ConsoleInformation *console, grs_bitmap *image) +{ + if(!console) + return 1; + + /* Free the background from the console */ + if (image == NULL) { + if (console->BackgroundImage) + gr_free_bitmap(console->BackgroundImage); + console->BackgroundImage = NULL; +#if 0 + SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); +#endif + return 0; + } + + /* Load a new background */ + if (console->BackgroundImage) + gr_free_bitmap(console->BackgroundImage); + console->BackgroundImage = gr_create_bitmap(console->ConsoleSurface->cv_w, console->ConsoleSurface->cv_h); + gr_bitmap_scale_to(image, console->BackgroundImage); + +#if 0 + SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); +#endif + gr_bm_bitblt(console->BackgroundImage->bm_w, console->InputBackground->bm_h, 0, 0, 0, console->ConsoleSurface->cv_h - console->ConsoleSurface->cv_font->ft_h, console->BackgroundImage, console->InputBackground); + + return 0; +} + +/* Sets font info for the console */ +void CON_Font(ConsoleInformation *console, grs_font *font, int fg, int bg) +{ + grs_canvas *canv_save; + + canv_save = grd_curcanv; + gr_set_current_canvas(console->ConsoleSurface); + gr_set_curfont(font); + gr_set_fontcolor(fg, bg); + gr_set_current_canvas(canv_save); +} + +/* takes a new x and y of the top left of the console window */ +void CON_Position(ConsoleInformation *console, int x, int y) { + if(!console) + return; + + if(x < 0 || x > console->OutputScreen->sc_w - console->ConsoleSurface->cv_w) + console->DispX = 0; + else + console->DispX = x; + + if(y < 0 || y > console->OutputScreen->sc_h - console->ConsoleSurface->cv_h) + console->DispY = 0; + else + console->DispY = y; +} + +void gr_init_bitmap_alloc( grs_bitmap *bm, int mode, int x, int y, int w, int h, int bytesperline); +/* resizes the console, has to reset alot of stuff + * returns 1 on error */ +int CON_Resize(ConsoleInformation *console, int x, int y, int w, int h) +{ + if(!console) + return 1; + + /* make sure that the size of the console is valid */ + if(w > console->OutputScreen->sc_w || w < console->ConsoleSurface->cv_font->ft_w * 32) + w = console->OutputScreen->sc_w; + if(h > console->OutputScreen->sc_h || h < console->ConsoleSurface->cv_font->ft_h) + h = console->OutputScreen->sc_h; + if(x < 0 || x > console->OutputScreen->sc_w - w) + console->DispX = 0; + else + console->DispX = x; + if(y < 0 || y > console->OutputScreen->sc_h - h) + console->DispY = 0; + else + console->DispY = y; + + /* resize console surface */ + gr_free_bitmap_data(&console->ConsoleSurface->cv_bitmap); + gr_init_bitmap_alloc(&console->ConsoleSurface->cv_bitmap, BM_LINEAR, 0, 0, w, h, w); + + /* Load the dirty rectangle for user input */ + gr_free_bitmap(console->InputBackground); + console->InputBackground = gr_create_bitmap(w, console->ConsoleSurface->cv_font->ft_h); + + /* Now reset some stuff dependent on the previous size */ + console->ConsoleScrollBack = 0; + + /* Reload the background image (for the input text area) in the console */ + if(console->BackgroundImage) { +#if 0 + SDL_FillRect(console->InputBackground, NULL, SDL_MapRGBA(console->ConsoleSurface->format, 0, 0, 0, SDL_ALPHA_OPAQUE)); +#endif + gr_bm_bitblt(console->BackgroundImage->bm_w, console->InputBackground->bm_h, 0, 0, 0, console->ConsoleSurface->cv_h - console->ConsoleSurface->cv_font->ft_h, console->BackgroundImage, console->InputBackground); + } + +#if 0 + /* restore the alpha level */ + CON_Alpha(console, console->ConsoleAlpha); +#endif + return 0; +} + +/* Transfers the console to another screen surface, and adjusts size */ +int CON_Transfer(ConsoleInformation *console, grs_screen *new_outputscreen, int x, int y, int w, int h) +{ + if(!console) + return 1; + + console->OutputScreen = new_outputscreen; + + return(CON_Resize(console, x, y, w, h)); +} + +/* Sets the topmost console for input */ +void CON_Topmost(ConsoleInformation *console) { + grs_canvas *canv_save; + short orig_color; + + if(!console) + return; + + // Make sure the blinking cursor is gone + if(Topmost) { + canv_save = grd_curcanv; + gr_set_current_canvas(Topmost->ConsoleSurface); + + gr_bitmap(0, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->InputBackground); + orig_color = FG_COLOR; + gr_string(CON_CHAR_BORDER, Topmost->ConsoleSurface->cv_h - Topmost->ConsoleSurface->cv_font->ft_h, Topmost->VCommand); + FG_COLOR = orig_color; + + gr_set_current_canvas(canv_save); + } + Topmost = console; +} + +/* Sets the Prompt for console */ +void CON_SetPrompt(ConsoleInformation *console, char* newprompt) { + if(!console) + return; + + //check length so we can still see at least 1 char :-) + if(strlen(newprompt) < console->VChars) + console->Prompt = d_strdup(newprompt); + else + CON_Out(console, "prompt too long. (max. %i chars)", console->VChars - 1); +} + +/* Sets the key that deactivates (hides) the console. */ +void CON_SetHideKey(ConsoleInformation *console, int key) { + if(console) + console->HideKey = key; +} + +void CON_SetHideFunction(ConsoleInformation *console, void(*HideFunction)(void)) { + if(console) + console->HideFunction = HideFunction; +} + +void Default_HideFunction(void) { +} + +/* Executes the command entered */ +void CON_Execute(ConsoleInformation *console, char* command) { + if(console) + console->CmdFunction(console, command); +} + +void CON_SetExecuteFunction(ConsoleInformation *console, void(*CmdFunction)(ConsoleInformation *console2, char* command)) { + if(console) + console->CmdFunction = CmdFunction; +} + +void Default_CmdFunction(ConsoleInformation *console, char* command) { + CON_Out(console, " No CommandFunction registered"); + CON_Out(console, " use 'CON_SetExecuteFunction' to register one"); + CON_Out(console, " "); + CON_Out(console, "Unknown Command \"%s\"", command); +} + +void CON_SetTabCompletion(ConsoleInformation *console, char*(*TabFunction)(char* command)) { + if(console) + console->TabFunction = TabFunction; +} + +void CON_TabCompletion(ConsoleInformation *console) { + int i,j; + char* command; + + if(!console) + return; + + command = d_strdup(console->LCommand); + command = console->TabFunction(command); + + if(!command) + return; //no tab completion took place so return silently + + j = strlen(command); + if(j > CON_CHARS_PER_LINE - 2) + j = CON_CHARS_PER_LINE-1; + + memset(console->LCommand, 0, CON_CHARS_PER_LINE); + console->CursorPos = 0; + + for(i = 0; i < j; i++) { + console->CursorPos++; + console->LCommand[i] = command[i]; + } + //add a trailing space + console->CursorPos++; + console->LCommand[j] = ' '; + console->LCommand[j+1] = '\0'; +} + +char* Default_TabFunction(char* command) { + CON_Out(Topmost, " No TabFunction registered"); + CON_Out(Topmost, " use 'CON_SetTabCompletion' to register one"); + CON_Out(Topmost, " "); + return NULL; +} + +void Cursor_Left(ConsoleInformation *console) { + char temp[CON_CHARS_PER_LINE]; + + if(Topmost->CursorPos > 0) { + Topmost->CursorPos--; + strcpy(temp, Topmost->RCommand); + strcpy(Topmost->RCommand, &Topmost->LCommand[strlen(Topmost->LCommand)-1]); + strcat(Topmost->RCommand, temp); + Topmost->LCommand[strlen(Topmost->LCommand)-1] = '\0'; + //CON_Out(Topmost, "L:%s, R:%s", Topmost->LCommand, Topmost->RCommand); + } +} + +void Cursor_Right(ConsoleInformation *console) { + char temp[CON_CHARS_PER_LINE]; + + if(Topmost->CursorPos < strlen(Topmost->Command)) { + Topmost->CursorPos++; + strncat(Topmost->LCommand, Topmost->RCommand, 1); + strcpy(temp, Topmost->RCommand); + strcpy(Topmost->RCommand, &temp[1]); + //CON_Out(Topmost, "L:%s, R:%s", Topmost->LCommand, Topmost->RCommand); + } +} + +void Cursor_Home(ConsoleInformation *console) { + char temp[CON_CHARS_PER_LINE]; + + Topmost->CursorPos = 0; + strcpy(temp, Topmost->RCommand); + strcpy(Topmost->RCommand, Topmost->LCommand); + strncat(Topmost->RCommand, temp, strlen(temp)); + memset(Topmost->LCommand, 0, CON_CHARS_PER_LINE); +} + +void Cursor_End(ConsoleInformation *console) { + Topmost->CursorPos = strlen(Topmost->Command); + strncat(Topmost->LCommand, Topmost->RCommand, strlen(Topmost->RCommand)); + memset(Topmost->RCommand, 0, CON_CHARS_PER_LINE); +} + +void Cursor_Del(ConsoleInformation *console) { + char temp[CON_CHARS_PER_LINE]; + + if(strlen(Topmost->RCommand) > 0) { + strcpy(temp, Topmost->RCommand); + strcpy(Topmost->RCommand, &temp[1]); + } +} + +void Cursor_BSpace(ConsoleInformation *console) { + if(Topmost->CursorPos > 0) { + Topmost->CursorPos--; + Topmost->Offset--; + if(Topmost->Offset < 0) + Topmost->Offset = 0; + Topmost->LCommand[strlen(Topmost->LCommand)-1] = '\0'; + } +} + +void Cursor_Add(ConsoleInformation *console, int event) +{ + if(strlen(Topmost->Command) < CON_CHARS_PER_LINE - 1) + { + Topmost->CursorPos++; + Topmost->LCommand[strlen(Topmost->LCommand)] = key_to_ascii(event); + Topmost->LCommand[strlen(Topmost->LCommand)] = '\0'; + } +} + +void Clear_Command(ConsoleInformation *console) { + Topmost->CursorPos = 0; + memset(Topmost->VCommand, 0, CON_CHARS_PER_LINE); + memset(Topmost->Command, 0, CON_CHARS_PER_LINE); + memset(Topmost->LCommand, 0, CON_CHARS_PER_LINE); + memset(Topmost->RCommand, 0, CON_CHARS_PER_LINE); +} + +void Clear_History(ConsoleInformation *console) { + int loop; + + for(loop = 0; loop <= console->LineBuffer - 1; loop++) + memset(console->ConsoleLines[loop], 0, CON_CHARS_PER_LINE); +} + +void Command_Up(ConsoleInformation *console) { + if(console->CommandScrollBack < console->TotalCommands - 1) { + /* move back a line in the command strings and copy the command to the current input string */ + console->CommandScrollBack++; + memset(console->RCommand, 0, CON_CHARS_PER_LINE); + console->Offset = 0; + strcpy(console->LCommand, console->CommandLines[console->CommandScrollBack]); + console->CursorPos = strlen(console->CommandLines[console->CommandScrollBack]); + CON_UpdateConsole(console); + } +} + +void Command_Down(ConsoleInformation *console) { + if(console->CommandScrollBack > -1) { + /* move forward a line in the command strings and copy the command to the current input string */ + console->CommandScrollBack--; + memset(console->RCommand, 0, CON_CHARS_PER_LINE); + memset(console->LCommand, 0, CON_CHARS_PER_LINE); + console->Offset = 0; + if(console->CommandScrollBack > -1) + strcpy(console->LCommand, console->CommandLines[console->CommandScrollBack]); + console->CursorPos = strlen(console->LCommand); + CON_UpdateConsole(console); + } +} + #include #include #include @@ -19,11 +1211,6 @@ #endif #include -#include -#ifdef CONSOLE -#include "CON_console.h" -#endif - #include "pstypes.h" #include "u_mem.h" #include "error.h" -- 2.39.2