/* Simple debugging component. Temporary */

#include "ttdebug.h"
#include "tttables.h"
#include "ttobjs.h"


#ifdef DEBUG_LEVEL_TRACE
  Byte  tt_trace_levels[trace_max];
#endif

#if defined(DEBUG_LEVEL_ERROR) || defined(DEBUG_LEVEL_TRACE)

#include <stdio.h>
#include <stdarg.h>
#include <string.h>


  typedef Byte ByteStr[2];
  typedef Byte WordStr[4];
  typedef Byte LongStr[8];
  typedef Byte DebugStr[128];

  static  DebugStr tempStr;

  static const String*  OpStr[256] = {
            "SVTCA y",       /* Set vectors to coordinate axis y    */
            "SVTCA x",       /* Set vectors to coordinate axis x    */
            "SPvTCA y",      /* Set Proj. vec. to coord. axis y     */
            "SPvTCA x",      /* Set Proj. vec. to coord. axis x     */
            "SFvTCA y",      /* Set Free. vec. to coord. axis y     */
            "SFvTCA x",      /* Set Free. vec. to coord. axis x     */
            "SPvTL //",      /* Set Proj. vec. parallel to segment  */
            "SPvTL +",       /* Set Proj. vec. normal to segment    */
            "SFvTL //",      /* Set Free. vec. parallel to segment  */
            "SFvTL +",       /* Set Free. vec. normal to segment    */
            "SPvFS",         /* Set Proj. vec. from stack           */
            "SFvFS",         /* Set Free. vec. from stack           */
            "GPV",           /* Get projection vector               */
            "GFV",           /* Get freedom vector                  */
            "SFvTPv",        /* Set free. vec. to proj. vec.        */
            "ISECT",         /* compute intersection                */

            "SRP0",          /* Set reference point 0               */
            "SRP1",          /* Set reference point 1               */
            "SRP2",          /* Set reference point 2               */
            "SZP0",          /* Set Zone Pointer 0                  */
            "SZP1",          /* Set Zone Pointer 1                  */
            "SZP2",          /* Set Zone Pointer 2                  */
            "SZPS",          /* Set all zone pointers               */
            "SLOOP",         /* Set loop counter                    */
            "RTG",           /* Round to Grid                       */
            "RTHG",          /* Round to Half-Grid                  */
            "SMD",           /* Set Minimum Distance                */
            "ELSE",          /* Else                                */
            "JMPR",          /* Jump Relative                       */
            "SCvTCi",        /* Set CVT                             */
            "SSwCi",         /*                                     */
            "SSW",           /*                                     */

            "DUP",
            "POP",
            "CLEAR",
            "SWAP",
            "DEPTH",
            "CINDEX",
            "MINDEX",
            "AlignPTS",
            "INS_$28",
            "UTP",
            "LOOPCALL",
            "CALL",
            "FDEF",
            "ENDF",
            "MDAP[-]",
            "MDAP[r]",

            "IUP[y]",
            "IUP[x]",
            "SHP[0]",
            "SHP[1]",
            "SHC[0]",
            "SHC[1]",
            "SHZ[0]",
            "SHZ[1]",
            "SHPIX",
            "IP",
            "MSIRP[0]",
            "MSIRP[1]",
            "AlignRP",
            "RTDG",
            "MIAP[-]",
            "MIAP[r]",

            "NPushB",
            "NPushW",
            "WS",
            "RS",
            "WCvtP",
            "RCvt",
            "GC[0]",
            "GC[1]",
            "SCFS",
            "MD[0]",
            "MD[1]",
            "MPPEM",
            "MPS",
            "FlipON",
            "FlipOFF",
            "DEBUG",

            "LT",
            "LTEQ",
            "GT",
            "GTEQ",
            "EQ",
            "NEQ",
            "ODD",
            "EVEN",
            "IF",
            "EIF",
            "AND",
            "OR",
            "NOT",
            "DeltaP1",
            "SDB",
            "SDS",

            "ADD",
            "SUB",
            "DIV",
            "MUL",
            "ABS",
            "NEG",
            "FLOOR",
            "CEILING",
            "ROUND[G]",
            "ROUND[B]",
            "ROUND[W]",
            "ROUND[?]",
            "NROUND[G]",
            "NROUND[B]",
            "NROUND[W]",
            "NROUND[?]",

            "WCvtF",
            "DeltaP2",
            "DeltaP3",
            "DeltaC1",
            "DeltaC2",
            "DeltaC3",
            "SROUND",
            "S45Round",
            "JROT",
            "JROF",
            "ROFF",
            "INS_$7B",
            "RUTG",
            "RDTG",
            "SANGW",
            "AA",

            "FlipPT",
            "FlipRgON",
            "FlipRgOFF",
            "INS_$83",
            "INS_$84",
            "ScanCTRL",
            "SDPVTL[0]",
            "SDPVTL[1]",
            "GetINFO",
            "IDEF",
            "ROLL",
            "MAX",
            "MIN",
            "ScanTYPE",
            "IntCTRL",
            "INS_$8F",

            "INS_$90",
            "INS_$91",
            "INS_$92",
            "INS_$93",
            "INS_$94",
            "INS_$95",
            "INS_$96",
            "INS_$97",
            "INS_$98",
            "INS_$99",
            "INS_$9A",
            "INS_$9B",
            "INS_$9C",
            "INS_$9D",
            "INS_$9E",
            "INS_$9F",

            "INS_$A0",
            "INS_$A1",
            "INS_$A2",
            "INS_$A3",
            "INS_$A4",
            "INS_$A5",
            "INS_$A6",
            "INS_$A7",
            "INS_$A8",
            "INS_$A9",
            "INS_$AA",
            "INS_$AB",
            "INS_$AC",
            "INS_$AD",
            "INS_$AE",
            "INS_$AF",

            "PushB[0]",
            "PushB[1]",
            "PushB[2]",
            "PushB[3]",
            "PushB[4]",
            "PushB[5]",
            "PushB[6]",
            "PushB[7]",
            "PushW[0]",
            "PushW[1]",
            "PushW[2]",
            "PushW[3]",
            "PushW[4]",
            "PushW[5]",
            "PushW[6]",
            "PushW[7]",

            "MDRP[G]",
            "MDRP[B]",
            "MDRP[W]",
            "MDRP[?]",
            "MDRP[rG]",
            "MDRP[rB]",
            "MDRP[rW]",
            "MDRP[r?]",
            "MDRP[mG]",
            "MDRP[mB]",
            "MDRP[mW]",
            "MDRP[m?]",
            "MDRP[mrG]",
            "MDRP[mrB]",
            "MDRP[mrW]",
            "MDRP[mr?]",
            "MDRP[pG]",
            "MDRP[pB]",

            "MDRP[pW]",
            "MDRP[p?]",
            "MDRP[prG]",
            "MDRP[prB]",
            "MDRP[prW]",
            "MDRP[pr?]",
            "MDRP[pmG]",
            "MDRP[pmB]",
            "MDRP[pmW]",
            "MDRP[pm?]",
            "MDRP[pmrG]",
            "MDRP[pmrB]",
            "MDRP[pmrW]",
            "MDRP[pmr?]",

            "MIRP[G]",
            "MIRP[B]",
            "MIRP[W]",
            "MIRP[?]",
            "MIRP[rG]",
            "MIRP[rB]",
            "MIRP[rW]",
            "MIRP[r?]",
            "MIRP[mG]",
            "MIRP[mB]",
            "MIRP[mW]",
            "MIRP[m?]",
            "MIRP[mrG]",
            "MIRP[mrB]",
            "MIRP[mrW]",
            "MIRP[mr?]",
            "MIRP[pG]",
            "MIRP[pB]",

            "MIRP[pW]",
            "MIRP[p?]",
            "MIRP[prG]",
            "MIRP[prB]",
            "MIRP[prW]",
            "MIRP[pr?]",
            "MIRP[pmG]",
            "MIRP[pmB]",
            "MIRP[pmW]",
            "MIRP[pm?]",
            "MIRP[pmrG]",
            "MIRP[pmrB]",
            "MIRP[pmrW]",
            "MIRP[pmr?]"
          };


  const String* Cur_U_Line( void* _exec )
  {
    String  s[32];

    Int op, i, n;

    PExecution_Context exec;

    exec = _exec;

    op = exec->code[ exec->IP ];

    sprintf( tempStr, "%04hx: %02hx  %s", exec->IP, op, OpStr[op] );

    if ( op == 0x40 )
    {
      n = exec->code[ exec->IP+1 ];
      sprintf( s, "(%d)", n );
      strncat( tempStr, s, 8 );

      if ( n > 20 ) n = 20; /* limit output */

      for ( i = 0; i < n; i++ )
      {
        sprintf( s, " $%02hx", exec->code[ exec->IP+i+2 ] );
        strncat( tempStr, s, 8 );
      }
    }
    else if ( op == 0x41 )
    {
      n = exec->code[ exec->IP+1 ];
      sprintf( s, "(%d)", n );
      strncat( tempStr, s, 8 );

      if (n > 20) n = 20; /* limit output */

      for ( i = 0; i < n; i++ )
      {
        sprintf( s, " $%02hx%02hx", exec->code[ exec->IP+i*2+2 ],
                                    exec->code[ exec->IP+i*2+3 ] );
        strncat( tempStr, s, 8 );
      }
    }
    else if ( (op & 0xF8) == 0xB0 )
    {
      n = op-0xB0;

      for ( i=0; i <= n; i++ )
      {
        sprintf( s, " $%02hx", exec->code[ exec->IP+i+1 ] );
        strncat( tempStr, s, 8 );
      }
    }
    else if ( (op & 0xF8) == 0xB8 )
    {
      n = op-0xB8;

      for ( i = 0; i <= n; i++ )
      {
        sprintf( s, " $%02hx%02hx", exec->code[ exec->IP+i*2+1 ],
                                  exec->code[ exec->IP+i*2+2 ] );
        strncat( tempStr, s, 8 );
      }
    }

    return (String*)tempStr;
  }

  /* the Print() function is defined in ttconfig.h   */
  /* it defaults to vprintf on systems which have it */

  void  TT_Message( const String*  fmt, ... )
  {
    va_list  ap;

    va_start( ap, fmt );
    Print( fmt, ap );
    va_end( ap );
  }


  void  TT_Panic( const String*  fmt, ... )
  {
    va_list  ap;

    va_start( ap, fmt );
    Print( fmt, ap );
    va_end( ap );

    exit( EXIT_FAILURE );
  }

#endif /* DEBUG */


/* END */
