home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser 2002 January / STC_CD_01_2002.iso / JAGUAR / JAG_SRC / SOURCE / DEBUGUI.C < prev    next >
C/C++ Source or Header  |  2001-08-18  |  26KB  |  936 lines

  1. ////////////////////////////////////////////////////////////////////////////////
  2. // Jagulator: Atari Jaguar Console Emulation Project (debugui.c)
  3. // -----------------------------------------------------------------------------
  4. // Jagulator is the Copyright (c) RealityMan 1998-2001 and is provided "as is" 
  5. // without any expressed or implied warranty. I have no Trademarks, Legal or 
  6. // otherwise. Atari, Jaguar and the Atari Logo are copyright Hasbro Inc. All 
  7. // other Copyrights and Trademarks are acknowledged. This project is in no way 
  8. // linked to Atari/Hasbro or other associated Atari companies.                
  9. //
  10. // 07-07-2001 GH: New Source, Rewritten for Release 1.5.0
  11. // 00-00-0000 GH: All Previous Source Considered as Development Code Only
  12.  
  13. #include "core.h"
  14.  
  15. ////////////////////////////////////////////////////////////////////////////////
  16. // Globals
  17.  
  18.    Con console;                        // Console Line Data
  19.    View view;                          // Console View Information
  20.    char statusline[128];               // Console Status Line
  21.    Win w_regs;                         // Register View
  22.    Win w_dm68;                         // 68000 Disassembly
  23.    Win w_dgpu;                         // GPU Disassembly
  24.    Win w_ddsp;                         // DSP Disassembly
  25.    Win w_data;                         // Data Disassembly
  26.    Win w_cons;                         // Console Window Information
  27.    int c_barfg = 0x0;                  // Bar Foreground Attribute
  28.    int c_barbg = 0x3;                  // Bar Background Attribute
  29.    int viewopen = 0;                   // View Open Flag
  30.    int exitflag = 0;                   // Exit Flag
  31.  
  32.    struct                              // Console Information
  33.    {
  34.       HANDLE hconsole;                 // Console Handle
  35.       HANDLE hconsoleinput;            // Console Input Handle
  36.       int sx, sy;                      // Console Size
  37.       int basey;
  38.       int cx, cy;                      // Cursor Position
  39.       int attr;                        // Current Attribute
  40.       int cix, ciy;                    // Output Buffer
  41.       int cicount;
  42.       CHAR_INFO ci[MAXSTRING];
  43.    } con;
  44.  
  45.    static char editline[256];          // Console Keyboard Handling
  46.    static int  editpos;
  47.    static char lastcmd[256];
  48.    static char breakcmd[256];
  49.    static char tmpcmd[256];
  50.    static char history[HISTORY][256];
  51.    static int  historypos;
  52.    static int  scrolling;
  53.  
  54. ////////////////////////////////////////////////////////////////////////////////
  55. // Exception Messages
  56.  
  57.    void exception( char *txt, ... )
  58.    {
  59.       #ifdef DEBUG
  60.       static char buf[256];            // String Buffer
  61.       va_list argp;                    // Argument Pointer
  62.  
  63.       va_start( argp, txt );           // Start of Arguments
  64.  
  65.       sprintf( buf, YEL"Exception: " );
  66.       vsprintf( buf + strlen(buf), txt, argp );
  67.       strcat( buf, "\n" );
  68.       print( buf );
  69.       #endif
  70.    }
  71.  
  72.  
  73. ////////////////////////////////////////////////////////////////////////////////
  74. // Error Messages
  75.  
  76.    void error( char *txt, ... )
  77.    {
  78.       #ifdef DEBUG
  79.       static char buf[256];            // String Pointer
  80.       va_list argp;                    // Argument Pointer
  81.  
  82.       va_start( argp, txt );           // Start of Arguments
  83.     
  84.       sprintf( buf, YEL"Error: " );
  85.       vsprintf( buf + strlen(buf), txt, argp );
  86.       strcat( buf, "\n" );
  87.       print( buf );
  88.       #endif
  89.    }
  90.  
  91. ////////////////////////////////////////////////////////////////////////////////
  92. // Warning Messages
  93.  
  94.    void warning( char *txt, ... )
  95.    {
  96.       #ifdef DEBUG
  97.       static char buf[256];            // String Pointer
  98.       va_list argp;                    // Argument Pointer
  99.  
  100.       va_start( argp, txt );           // Start of Arguments
  101.       
  102.       sprintf( buf, YEL"Warning: " );
  103.       vsprintf( buf + strlen(buf), txt, argp );
  104.       strcat( buf, "\n" );
  105.       printf( buf );
  106.       #endif
  107.    }
  108.  
  109. ////////////////////////////////////////////////////////////////////////////////
  110. // Read Input Event
  111.  
  112.    int readevent( int dopeek )
  113.    {
  114.       INPUT_RECORD inp;
  115.       DWORD num;
  116.       int ascii, vkey, down, res;
  117.  
  118.       if( !con.hconsole ) return( 0 );
  119.  
  120.       if( dopeek )
  121.       {
  122.          PeekConsoleInput( con.hconsoleinput, &inp, 1, &num );
  123.          if( !num ) return( 0 );
  124.       }
  125.       ReadConsoleInput( con.hconsoleinput, &inp, 1, &num );
  126.  
  127.       if( inp.EventType == KEY_EVENT )
  128.       {
  129.          ascii = inp.Event.KeyEvent.uChar.AsciiChar;
  130.          vkey  = inp.Event.KeyEvent.wVirtualKeyCode;
  131.          down  = inp.Event.KeyEvent.bKeyDown;
  132.          res = 0;
  133.  
  134.          if( vkey >= 'A' && vkey <= 'Z' && (ascii < 'A' || ascii > 'z') )
  135.          {
  136.             res = vkey;
  137.          }
  138.          else if( vkey >= VK_F1 && vkey <= VK_F12 )
  139.          {
  140.             res = (KEY_F1 + vkey - VK_F1);
  141.          }
  142.          else switch( vkey )
  143.          {
  144.             case VK_DELETE: res = (KEY_DEL);    break;
  145.             case VK_UP:     res = (KEY_UP);     break;
  146.             case VK_DOWN:   res = (KEY_DOWN);   break;
  147.             case VK_LEFT:   res = (KEY_LEFT);   break;
  148.             case VK_RIGHT:  res = (KEY_RIGHT);  break;
  149.             case VK_PRIOR:  res = (KEY_PGUP);   break;
  150.             case VK_NEXT:   res = (KEY_PGDN);   break;
  151.             case VK_HOME:   res = (KEY_HOME);   break;
  152.             case VK_END:    res = (KEY_END);    break;
  153.             default:        res = (ascii);      break;
  154.          }
  155.  
  156.          if( !down ) res |= KEY_RELEASE;
  157.  
  158.          return( res );
  159.       }
  160.  
  161.       return( 0 );
  162.    }
  163.  
  164. ////////////////////////////////////////////////////////////////////////////////
  165. // Console Read Keystroke
  166.  
  167.    int con_readkey_noblock( void )
  168.    {
  169.       if( !con.hconsole ) return( 0 );
  170.       return( readevent( 1 ) );
  171.    }
  172.  
  173. ////////////////////////////////////////////////////////////////////////////////
  174. // Console Sleep
  175.  
  176.    void con_sleep( int ms )
  177.    {
  178.       Sleep( ms );
  179.    }
  180.  
  181. ////////////////////////////////////////////////////////////////////////////////
  182. // Console Print Character
  183.  
  184.    void con_printchar( int ch )
  185.    {
  186.       if( !con.hconsole ) return;
  187.  
  188.       if( con.cx != con.cix + con.cicount || con.cy != con.ciy || ch == -1 )
  189.       {
  190.          if( con.cicount )
  191.          {
  192.             COORD cisize, cibase;
  193.             SMALL_RECT region;
  194.  
  195.             cisize.X = con.cicount;
  196.             cisize.Y = 1;
  197.             cibase.X = 0;
  198.             cibase.Y = 0;
  199.  
  200.             region.Left   = con.cix;
  201.             region.Top    = con.ciy + con.basey;
  202.             region.Right  = con.cix + con.cicount - 1;
  203.             region.Bottom = con.ciy + con.basey;
  204.             WriteConsoleOutput( con.hconsole, con.ci, cisize, cibase, ®ion );
  205.          }
  206.  
  207.          con.cicount = 0;
  208.          con.cix = con.cx;
  209.          con.ciy = con.cy;
  210.  
  211.          if( ch == -1 ) return;
  212.       }
  213.  
  214.       con.ci[con.cicount].Char.AsciiChar = ch;
  215.       con.ci[con.cicount].Attributes = con.attr;
  216.       con.cicount++;
  217.       con.cx++;
  218.    }
  219.  
  220. ////////////////////////////////////////////////////////////////////////////////
  221. // Console Print
  222.  
  223.    void con_print( char *text )
  224.    {
  225.       static CHAR_INFO ci[MAXSTRING];
  226.       int i = 0;
  227.  
  228.       if( !con.hconsole ) return;
  229.       while( *text )
  230.       {
  231.          if( *text == 0x01 )
  232.          {                             // Foreground Set
  233.             con.attr &= 0xfff0;
  234.             con.attr |= text[1] & 15;
  235.             text += 2;
  236.          }
  237.          else if( *text == 0x02 )
  238.          {                             // Background Set
  239.             con.attr &= 0xff0f;
  240.             con.attr |= (text[1] & 15) << 4;
  241.             text += 2;
  242.          }
  243.          else if( *text == '\n' )
  244.          {
  245.             con_gotoxy( 0, con.cy + 1 );
  246.             text++;
  247.          }
  248.          else
  249.          {
  250.             con_printchar( *text++ );
  251.          }
  252.       }
  253.    }
  254.  
  255. ////////////////////////////////////////////////////////////////////////////////
  256. // Console Tab
  257.  
  258.    void con_tabto( int ch, int x )
  259.    {
  260.       if( !con.hconsole ) return;
  261.       while( con.cx < con.sx && con.cx < x )
  262.       {
  263.          con_printchar( ch );
  264.       }
  265.    }
  266.  
  267. ////////////////////////////////////////////////////////////////////////////////
  268. // Console Formatted Output
  269.  
  270.    void con_printf( char *txt, ... )
  271.    {
  272.       static char buf[MAXSTRING];
  273.       va_list argp;
  274.  
  275.       va_start( argp, txt );
  276.       vsprintf( buf, txt, argp );
  277.       con_print( buf );
  278.    }
  279.  
  280. ////////////////////////////////////////////////////////////////////////////////
  281. // Set Console X, Y
  282.  
  283.    void con_cursorxy( int x, int y, int size )
  284.    {
  285.       COORD c;
  286.       CONSOLE_CURSOR_INFO ci;
  287.  
  288.       if( !con.hconsole ) return;
  289.       c.X = x;
  290.       c.Y = y + con.basey;
  291.       if( size < 1 || size > 100 )
  292.       {
  293.          ci.bVisible = FALSE;
  294.          ci.dwSize = 50;
  295.       }
  296.       else
  297.       {
  298.          ci.bVisible = TRUE;
  299.          ci.dwSize = size;
  300.       }
  301.       SetConsoleCursorInfo( con.hconsole, &ci );
  302.       SetConsoleCursorPosition( con.hconsole, c );
  303.    }
  304.  
  305. ////////////////////////////////////////////////////////////////////////////////
  306. // Set Fore and Background Console Attribute
  307.  
  308.    void con_attr2( int fg, int bg )
  309.    {
  310.       con.attr = (bg << 4) | fg;
  311.    }
  312.  
  313. ////////////////////////////////////////////////////////////////////////////////
  314. // Return Console Rows
  315.  
  316.    int con_rows( void )
  317.    {
  318.       return( con.sy );
  319.    }
  320.  
  321. ////////////////////////////////////////////////////////////////////////////////
  322. // Goto Console X,Y Coordinate
  323.  
  324.    void con_gotoxy( int x, int y )
  325.    {
  326.       if( !con.hconsole ) return;
  327.       con_printchar( -1 );
  328.       con.cx = x;
  329.       con.cy = y;
  330.    }
  331.  
  332. ////////////////////////////////////////////////////////////////////////////////
  333. // Deinitialise Console
  334.  
  335.    void con_deinit( void )
  336.    {
  337.       FreeConsole();
  338.    }
  339.  
  340. ////////////////////////////////////////////////////////////////////////////////
  341. // Clear Console Display
  342.  
  343.    void con_clear( void )
  344.    {
  345.       COORD zero;
  346.       int x;
  347.     
  348.       zero.X = 0;
  349.       zero.Y = 0;
  350.     
  351.       FillConsoleOutputCharacter( con.hconsole, ' ', 65535, zero, &x );
  352.       FillConsoleOutputAttribute( con.hconsole, 0x7, 65535, zero, &x );
  353.       
  354.       con.cx = con.cy = 0;
  355.    }
  356.  
  357. ////////////////////////////////////////////////////////////////////////////////
  358. // Resize Console
  359.  
  360.    void ResizeConsole( HANDLE hConsole, SHORT xSize, SHORT ySize )
  361.    {
  362.       CONSOLE_SCREEN_BUFFER_INFO csbi; // Hold Current Console Buffer Info 
  363.       BOOL bSuccess;   
  364.       SMALL_RECT srWindowRect;         // Hold the New Console Size 
  365.       COORD coordScreen;    
  366.       
  367.       bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
  368.       
  369.       // Get the Largest Size we can size the Console Window to 
  370.       coordScreen = GetLargestConsoleWindowSize( hConsole );
  371.   
  372.       // Define the New Console Window Size and Scroll Position 
  373.       srWindowRect.Right  = (SHORT)(min(xSize, coordScreen.X) - 1);
  374.       srWindowRect.Bottom = (SHORT)(min(ySize, coordScreen.Y) - 1);
  375.       srWindowRect.Left   = srWindowRect.Top = (SHORT)0;
  376.   
  377.       // Define the New Console Buffer Size    
  378.       coordScreen.X = xSize;
  379.       coordScreen.Y = ySize;
  380.   
  381.       // If the Current Buffer is Larger than what we want, Resize the 
  382.       // Console Window First, then the Buffer 
  383.       if( (DWORD)csbi.dwSize.X * csbi.dwSize.Y > (DWORD) xSize * ySize)
  384.       {
  385.          bSuccess = SetConsoleWindowInfo( hConsole, TRUE, &srWindowRect );
  386.          bSuccess = SetConsoleScreenBufferSize( hConsole, coordScreen );
  387.       }
  388.   
  389.       // If the Current Buffer is Smaller than what we want, Resize the 
  390.       // Buffer First, then the Console Window 
  391.       if( (DWORD)csbi.dwSize.X * csbi.dwSize.Y < (DWORD) xSize * ySize )
  392.       {
  393.          bSuccess = SetConsoleScreenBufferSize( hConsole, coordScreen );
  394.          bSuccess = SetConsoleWindowInfo( hConsole, TRUE, &srWindowRect );
  395.       }
  396.   
  397.       // If the Current Buffer *is* the Size we want, Don't do anything! 
  398.       return;
  399.    }
  400.  
  401. ////////////////////////////////////////////////////////////////////////////////
  402. // Check if Console has been Resized
  403.  
  404.    int con_resized( void )
  405.    {
  406.       int resized = 0, x, y;
  407.       CONSOLE_SCREEN_BUFFER_INFO info;
  408.  
  409.       GetConsoleScreenBufferInfo( con.hconsole, &info );
  410.  
  411.       x = info.srWindow.Right  - info.srWindow.Left + 1;
  412.       y = info.srWindow.Bottom - info.srWindow.Top  + 1;
  413.  
  414.       con.basey = info.srWindow.Top;
  415.  
  416.       if( x != con.sx )
  417.       {
  418.          resized = 1;
  419.          con.sx  = x;
  420.       }
  421.       if( y != con.sy )
  422.       {
  423.          resized = 1;
  424.          con.sy  = y;
  425.       }
  426.  
  427.       return( resized );
  428.    }
  429.  
  430. ////////////////////////////////////////////////////////////////////////////////
  431. // Open New Console
  432.  
  433.    void con_opennew( void )
  434.    {
  435.       FreeConsole();
  436.       AllocConsole();
  437.       
  438.       #ifdef RELEASE
  439.       ResizeConsole( GetStdHandle(STD_OUTPUT_HANDLE), 80, 16 );
  440.       #else
  441.       ResizeConsole( GetStdHandle(STD_OUTPUT_HANDLE), 80, 60 );
  442.       #endif
  443.    }
  444.  
  445. ////////////////////////////////////////////////////////////////////////////////
  446. // Initialise Console
  447.  
  448.    void con_init( void )
  449.    {
  450.       memset( &con, 0, sizeof(con) );  // Initialise Console Information
  451.  
  452.       con_opennew();                   // Open New Console
  453.  
  454.       con.hconsole = GetStdHandle(STD_OUTPUT_HANDLE);
  455.       con.hconsoleinput = GetStdHandle(STD_INPUT_HANDLE);
  456.       con_resized();
  457.       con.sy--;                        // Force Another Resize
  458.       con.attr = 0x0F;
  459.    }
  460.  
  461.    void con_initdummy( void )
  462.    {
  463.       memset( &con, 0, sizeof(con) );
  464.       con.sx = 80;
  465.       con.sy = 50;
  466.    }
  467.  
  468. ////////////////////////////////////////////////////////////////////////////////
  469. // Set Exit Flag
  470.  
  471.    void exitnow( void )
  472.    {
  473.       exitflag = 1;
  474.    }
  475.  
  476. ////////////////////////////////////////////////////////////////////////////////
  477. // Execute a Command
  478.  
  479.    void docommand( char *editline )
  480.    {
  481.       int i;
  482.  
  483.       if( !*editline ) return;
  484.       if( *editline == '+' ) strcpy( editline, lastcmd );
  485.       else strcpy( lastcmd, editline );
  486.       // Put to History (Unless Same as Last)
  487.       if( strcmp( editline, history[0] ) )
  488.       {
  489.          for( i = HISTORY - 1; i > 0; i-- )
  490.          {
  491.             strcpy( history[i], history[i-1] );
  492.          }
  493.          strcpy( history[0], editline );
  494.       }
  495.       historypos = -1;
  496.       command( editline );
  497.       conkey( 0 );
  498.       view_changed( VIEW_ALL );
  499.    }
  500.  
  501. ////////////////////////////////////////////////////////////////////////////////
  502. // View Status Line
  503.  
  504.    void view_status( char *text )
  505.    {
  506.       #ifdef DEBUG
  507.       int len = strlen(text);
  508.     
  509.       if( len > 78 ) len = 78;
  510.       memset( statusline, ' ', 80 );
  511.       statusline[80] = 0;
  512.       memcpy( statusline + 1, text, len );
  513.  
  514.       con_gotoxy( 0, con_rows() - 1 );
  515.       con_attr2( 0, 3 );
  516.       con_print( statusline );
  517.       #endif
  518.    }
  519.  
  520. ////////////////////////////////////////////////////////////////////////////////
  521. // View Console Window
  522.  
  523.    void view_cons( void )
  524.    {
  525.       #ifdef DEBUG
  526.       int c_cur = 0x03;
  527.       int c_txt = 0x02;
  528.       int c_bg = 0x00;
  529.       int y, i;
  530.  
  531.       y = w_cons.y;
  532.       con_gotoxy( 0, y++ );
  533.       con_attr2( c_barfg, c_barbg );
  534.       con_tabto( '─', 2 );
  535.       con_printf(" Debug Console ");
  536.       con_tabto( '─', 256 );
  537.  
  538.       i = view.consolerow + w_cons.sy - 2;
  539.       while( y < w_cons.y + w_cons.sy )
  540.       {
  541.          if( !i ) con_cursorxy( view.consolecursor, y, 25 );
  542.          con_gotoxy( 0, y++ );
  543.          con_attr2( c_txt, c_bg );
  544.          con_print( console.line[i--] );
  545.          con_tabto( ' ', 256 );
  546.       }
  547.  
  548.       if( view.consolerow > 0 ) con_cursorxy( 0, 0, 0 );
  549.       #endif
  550.    }
  551.  
  552. ////////////////////////////////////////////////////////////////////////////////
  553. // Check Console View Size
  554.  
  555.    void view_checksize( void )
  556.    {
  557.       int h, y;
  558.  
  559.       h = con_rows();
  560.       w_cons.sy = h - 1;
  561.       view.consrows = w_cons.sy-1;
  562.  
  563.       y = 0;
  564.       w_cons.y = y; 
  565.       y += w_cons.sy;
  566.    }
  567.  
  568. ////////////////////////////////////////////////////////////////////////////////
  569. // Redraw Console View
  570.  
  571.    void view_redraw( void )
  572.    {
  573.       if( !view.changed )
  574.          return;
  575.  
  576.       if( con_resized() || (view.changed & VIEW_RESIZE) )
  577.          view_checksize();
  578.  
  579.       if( view.changed & VIEW_CLEAR )
  580.          con_clear();
  581.  
  582.       if( view.changed & VIEW_CONS )
  583.          view_cons();
  584.  
  585.       con_gotoxy( 0, con_rows() - 1 );
  586.       con_attr2( 0, 3 );
  587.       con_print( statusline );
  588.  
  589.       con_gotoxy( 0, 0 );              // Will Flush Output Buffers
  590.       view.changed = 0;
  591.    }
  592.  
  593. ////////////////////////////////////////////////////////////////////////////////
  594. // Write to Console
  595.  
  596.    void view_writeconsole( char *text )
  597.    {
  598.       if( !viewopen ) return;
  599.  
  600.       while( *text )
  601.       {
  602.          if( *text == 0x1 || *text == 0x2 )
  603.          {
  604.             console.line[0][console.writepos++] = *text++;
  605.             console.line[0][console.writepos++] = *text;
  606.          }
  607.          else if( *text == '\r' )
  608.          {
  609.             console.line[0][console.writepos] = 0;
  610.             console.writepos = 0;
  611.          }
  612.          else if( *text == '\n' )
  613.          {
  614.             char *p;
  615.             console.line[0][console.writepos] = 0;
  616.             console.writepos = 0;
  617.             // Scroll
  618.             p = console.line[LINES-1];
  619.             memmove(console.line+1,console.line+0,sizeof(char *)*(LINES-1));
  620.             console.line[0] = p;
  621.             memset( console.line[0], 0, LINELEN );
  622.          }
  623.          else if( console.writepos < LINELEN - 1 )
  624.          {
  625.             console.line[0][console.writepos++] = *text;
  626.          }
  627.          text++;
  628.          if( console.writepos > 80 ) console.writepos = 80;
  629.       }
  630.    }
  631.  
  632. ////////////////////////////////////////////////////////////////////////////////
  633. // Update Log
  634.  
  635.    void printtxt( char *txt )
  636.    {
  637.       static FILE *logfile;            // File Pointer
  638.       char *p;                         // Character Pointer
  639.       static int printedstuff = 0;     // Printed Flag
  640.       static int flushcnt = 0;         // Flush Counter
  641.  
  642.       if( !logfile )                   // Open Log if Not Already Opened
  643.          logfile = fopen( "jagulator.log", "wt" );
  644.  
  645.       if( !txt )                       // Return if No Output
  646.       {
  647.          if( flushcnt )
  648.          {
  649.             flushcnt = 0;              // Zero Flush Count
  650.             fflush( logfile );
  651.          }
  652.          return;
  653.       }
  654.  
  655.       flushcnt++;                      // Increment Flush Count
  656.  
  657.       view_writeconsole( txt );
  658.  
  659.       if( flushcnt > 1000 )            // Redraw Screen Every 1000 Messages
  660.          flushdisplay();
  661.  
  662.       p = txt;                         // Set Pointer
  663.       while( *p )                      // While Valid Text Strip Codes
  664.       {
  665.          if( *p == 0x01 ) p += 2;
  666.          else if( *p == 0x02 ) p += 2;
  667.          else break;
  668.       }
  669.  
  670.       fputs( p, logfile );             // Write to Logfile
  671.    }
  672.  
  673. ////////////////////////////////////////////////////////////////////////////////
  674. // Flush Log
  675.  
  676.    void flushlog( void )
  677.    {
  678.       printtxt( NULL );
  679.    }
  680.  
  681. ////////////////////////////////////////////////////////////////////////////////
  682. // Flush Console Display
  683.  
  684.    void flushdisplay( void )
  685.    {
  686.       flushlog();
  687.       view_changed( VIEW_ALL );
  688.       view_redraw();
  689.    }
  690.  
  691. ////////////////////////////////////////////////////////////////////////////////
  692. // Set View Changed Flag
  693.  
  694.    void view_changed( int which )
  695.    {
  696.       view.changed |= which;
  697.    }
  698.  
  699. ////////////////////////////////////////////////////////////////////////////////
  700. // Open Debug Console View
  701.  
  702.    void view_open( void )
  703.    {
  704.       int i;                           // Iterator
  705.       static char buf[256];            // Temp Buffer
  706.  
  707.       view.changed = -1;               // Initialise View Changed Flag
  708.       view.active  = 0;                // Initialise View Active Flag
  709.  
  710.       con_initdummy();
  711. /*
  712.       con_init();
  713.       wsprintf( buf, "%s - %s v%i.%i.%i (%s)",
  714.                 APPNAME, TITLE, MAJORREV, MINORREV, PATCHLVL, PLATFORM );
  715.       SetConsoleTitle( buf );
  716. */
  717.       memset( &console, 0, sizeof(console) );
  718.       for( i = 0; i < LINES; i++ )
  719.       {
  720.          console.line[i] = console.linedata[i];
  721.       }
  722.  
  723.       viewopen = 1;                    // Set View Open Flag
  724.    }
  725.  
  726. ////////////////////////////////////////////////////////////////////////////////
  727. // Close Debug Console View
  728.  
  729.    void view_close( void )
  730.    {
  731.       viewopen = 0;                    // Unset View Open Flag
  732.       con_clear();
  733.       con_deinit();
  734.    }
  735.  
  736. ////////////////////////////////////////////////////////////////////////////////
  737. // Generic Print
  738.  
  739.    void print( char *txt, ... )
  740.    {
  741.       static char buf[256];            // String Buffer
  742.       va_list argp;                    // Argument Pointer
  743.  
  744.       va_start( argp, txt );           // Start of Arguments
  745.       if( !txt )                       // Return if No Output
  746.       {
  747.          printtxt( NULL );
  748.          return;
  749.       }
  750.  
  751.       vsprintf( buf, txt, argp );      // Format Text
  752.       printtxt( buf );                 // Write Text
  753.    }
  754.  
  755. ////////////////////////////////////////////////////////////////////////////////
  756. // Debug User Interface Key Handling
  757.  
  758.    void debugui_key( int a )
  759.    {
  760.       int flag = 1;
  761.  
  762.       if( a >= KEY_F1 && a <= KEY_F12 ) command_fkey( a );
  763.       else
  764.       {
  765.          flag = 0;
  766.          if( a >= 32 && a < 256 && view.active != WIN_CONS )
  767.          {
  768.             view.active = WIN_CONS;
  769.             flag = 1;
  770.          }
  771.          if( view.active == WIN_CONS ) conkey( a );
  772.       }
  773.  
  774.       if( flag ) view_changed( VIEW_ALL );
  775.    }
  776.  
  777. ////////////////////////////////////////////////////////////////////////////////
  778. // Console Key Handling
  779.  
  780.    void conkey( int a )
  781.    {
  782.       int editlen = strlen(editline);
  783.       int resetrow = 1, x;
  784.  
  785.       switch( a )
  786.       {
  787.          case KEY_PGUP:
  788.             resetrow = 0;
  789.             view.consolerow += view.consrows - 1;
  790.             scrolling = 1;
  791.             break;
  792.          case KEY_PGDN:
  793.             resetrow = 0;
  794.             if( view.consolerow == 0 ) scrolling = 0;
  795.             else scrolling = 1;
  796.             view.consolerow -= view.consrows - 1;
  797.             break;
  798.          case KEY_UP:
  799.             if( scrolling )
  800.             {
  801.                resetrow = 0;
  802.                view.consolerow += 1;
  803.             }
  804.             else
  805.             {
  806.                x = historypos + 1;
  807.                if( x < HISTORY && *history[x] )
  808.                {
  809.                   historypos = x;
  810.                   strcpy( editline, history[historypos] );
  811.                   editpos=strlen( editline );
  812.                }
  813.             }
  814.             break;
  815.          case KEY_DOWN:
  816.             if( scrolling )
  817.             {
  818.                resetrow = 0;
  819.                view.consolerow -= 1;
  820.             }
  821.             else
  822.             {
  823.                x = historypos - 1;
  824.                if( x > 0 && *history[x] )
  825.                {
  826.                   historypos = x;
  827.                   strcpy( editline, history[historypos] );
  828.                   editpos = strlen(editline);
  829.                }
  830.             }
  831.             break;
  832.          case KEY_LEFT:
  833.             editpos--;
  834.             if( editpos < 0 ) editpos = 0;
  835.             break;
  836.          case KEY_RIGHT:
  837.             editpos++;
  838.             if( editpos > editlen ) editpos = editlen;
  839.             break;
  840.          case KEY_HOME:
  841.             editpos = 0;
  842.             break;
  843.          case KEY_END:
  844.             editpos = editlen;
  845.             break;
  846.          case KEY_BKSPACE:
  847.             if( editpos == 0 ) break;
  848.             editpos--;
  849.          case KEY_DEL:
  850.             if( editline[editpos] )
  851.                memmove(editline+editpos,editline+editpos+1,256-1-editpos);
  852.             break;
  853.          case KEY_ENTER:
  854.             view_writeconsole( "\x01\x17" );
  855.             #ifndef RELEASE
  856.             print( ": %s\n", editline );
  857.             #endif
  858.             // Execute
  859.             docommand( editline );
  860.             // Flow On
  861.          case KEY_ESC:
  862.             // Clear
  863.             scrolling = 0;
  864.             *editline = 0;
  865.             editpos = 0;
  866.             break;
  867.          default:
  868.             if( a >= 32 && a < 256 )
  869.             {
  870.                memmove(editline+editpos+1,editline+editpos,256-1-editpos);
  871.                editline[editpos++] = a;
  872.             }
  873.             else resetrow = 0;
  874.             break;
  875.       }
  876.  
  877.       if( scrolling ) view_status( "Scrolling (Esc to Stop)" );
  878.       else view_status( "Ready... (PgUp to Scroll Console)" );
  879.       if( editpos > 77 ) editpos = 77;
  880.  
  881.       if( resetrow ) view.consolerow = 0;
  882.       if( view.consolerow < 0 ) view.consolerow = 0;
  883.       else if( view.consolerow > 1024 - 50 ) view.consolerow = 1024 - 50;
  884. #ifndef RELEASE
  885.       view.consolecursor = editpos + 2;
  886.       view_writeconsole( "\x01\x17: " );
  887.       view_writeconsole( editline );
  888.       view_writeconsole( "\r" );
  889. #endif
  890.       view_changed( VIEW_CONS );
  891.    }
  892.  
  893. ////////////////////////////////////////////////////////////////////////////////
  894. // Main Debug User Interface Loop
  895.  
  896.    void debugui( void )
  897.    {
  898.       int key;
  899.  
  900.       conkey( 0 );
  901.       while( !exitflag )
  902.       {
  903.          view_redraw();
  904.  
  905.          if( *breakcmd )
  906.          {
  907.             print( NORMAL":: %s\n", breakcmd );
  908.             strcpy( tmpcmd, breakcmd );
  909.             *breakcmd = 0;
  910.             command( tmpcmd );
  911.             flushdisplay();
  912.          }
  913.          else
  914.          {
  915.             key = con_readkey_noblock();
  916.             if( key )
  917.             {
  918.                 debugui_key( key );
  919.             }
  920.             else
  921.             {
  922.                 con_sleep( 10 );
  923.             }
  924.          }
  925.          con_sleep( 0 );
  926.       }
  927.    }
  928.  
  929.  
  930.  
  931.  
  932.  
  933.  
  934.  
  935.  
  936.