/*
** Name:      Ice-Breaker
** Version:   1.1
** Author:    Paul Manias
** Date:      December 1997.
** Copyright: DreamWorld Productions 1997.
** Compile:   sc IceBreaker.c nolink
**            PhxAss /IceAssembler.asm
**            slink FROM lib:c.o,IceBreaker.o,/IceAssembler.o TO IceBreakerCon LIBRARY LIB:sc.lib,LIB:Amiga.lib
**
** This is the entry code for IceBreaker, it sets things up so that the assembler
** code is ready to intercept debug messages.
**
*/

#include <proto/dpkernel.h>
#include <system/debug.h>

#include <proto/exec.h>
#include <proto/gmsdos.h>
#include <dos/dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern struct ExecBase    *SysBase;
extern far struct GFXBase *GFXBase;

#define LVODEBUGMESSAGE -378
#define LVOERRORMESSAGE -384
#define LVOSTEPBACK     -390
#define LVODPRINTF      -270

extern far WORD maxstep;
extern ULONG libDebugMessage(void);
extern ULONG libErrorMessage(void);
extern ULONG libStepBack(void);
__asm __saveds ULONG libDPrintF(register __a5 LONG *);

BYTE dbgstr[512];

struct Task *maintask;
struct Task *edittask = NULL;

BPTR conhandle=0;      /* Handle to output debug information */

void mainroutine(void);
long getlen(char string[]);
void wtext(char string[]);
BPTR openconsole(void);
void PrintUsage(void);

/***********************************************************************************
** Usage: IceBreaker [MAXSTEP n]
**
**
** ArgV: 0   = IceBreaker
**       1 - = Arguments
*/

LONG main(LONG argc, BYTE *argv[])
{
   void *oldDebugMessage;
   void *oldErrorMessage;
   void *oldStepBack;
   void *oldDPrintF;

   if (argc > 1) {
      if (argv[1][0] IS '?') {
         PrintUsage();
         return(NULL);
      }
      if (argc > 2) {
         if (stricmp(argv[1], "MAXSTEP") IS NULL) {
            maxstep = atoi(argv[2]);
         }
         else printf("Unknown argument %s.\n",argv[1]);
      }
   }

   if (maxstep <= NULL) maxstep = 2;

   dosDelay(5);

   maintask = FindTask(NULL);

   if (DPKBase = (struct DPKBase *) OpenLibrary("GMS:libs/dpkernel.library",0)) {
      if (DebugActive() IS ERR_OK) {
         if (GFXBase = (struct GFXBase *) OpenLibrary("graphics.library",0)) {
            if (conhandle = dosOutput()) {
               Forbid();
               oldDebugMessage = SetFunction((struct Library *)DPKBase,LVODEBUGMESSAGE,&libDebugMessage);
               oldErrorMessage = SetFunction((struct Library *)DPKBase,LVOERRORMESSAGE,&libErrorMessage);
               oldStepBack     = SetFunction((struct Library *)DPKBase,LVOSTEPBACK,&libStepBack);
               oldDPrintF      = SetFunction((struct Library *)DPKBase,LVODPRINTF,&libDPrintF);
               SumLibrary((struct Library *)DPKBase);
               Permit();

               mainroutine();

               Forbid();
               SetFunction((struct Library *)DPKBase,LVODEBUGMESSAGE,oldDebugMessage);
               SetFunction((struct Library *)DPKBase,LVOERRORMESSAGE,oldErrorMessage);
               SetFunction((struct Library *)DPKBase,LVOSTEPBACK,oldStepBack);
               SetFunction((struct Library *)DPKBase,LVODPRINTF,oldDPrintF);
               SumLibrary((struct Library *)DPKBase);
               Permit();
            }
            else printf("Could not find output handle.");
            CloseLibrary((struct Library *)GFXBase);
         }
         else printf("Could not open graphics.library");
         DebugInactive();
      }
      else printf("Debug initialisation failed.");
      CloseLibrary((struct Library *)DPKBase);
   }
   else printf("Could not open dpkernel.library.");

   return(NULL);
}

/***********************************************************************************/

void PrintUsage(void)
{
  printf("\n");
  printf("This program will wait until a program using GMS is executed.  Any\n");
  printf("debug messages that are sent while it is active will be intercepted\n");
  printf("and printed out to this window.\n\n");
  printf("Usage: IceBreaker [MAXSTEP n]\n\n");
}

/*********************************** MAIN LOOP *************************************/

void mainroutine(void)
{
  LONG result;

  wtext("\n");
  wtext("This program will wait until a program using GMS is executed.  Any\n");
  wtext("debug messages that are sent while it is active will be intercepted\n");
  wtext("and printed out to this window.\n\n");
  wtext("Press CTRL-C at any time to exit.\n\n");
  wtext("Type                 | Data\n");
  wtext("---------------------+---------------------------------------------\n");

  do {
     result = Wait(SIGBREAKF_CTRL_C);
  } while (!(result & SIGBREAKF_CTRL_C));

  wtext("[31m");
}

/***********************************************************************************/

void wtext(char string[]) {
  dosWrite(conhandle,(ULONG)string,getlen(string));
}

/***********************************************************************************/

long getlen(char string[]) {
  WORD length = NULL;

  while (string[length] != 0) {
    length++;
    if (length > 256) break;
  }
  return(length);
}

/***********************************************************************************/

__asm __saveds ULONG libDPrintF(register __a5 LONG *array)
{
  if (array != NULL) {
     sprintf(dbgstr,(BYTE *)array[0],array[1],array[2],array[3],array[4]);
     DMsg(dbgstr);
  }
  else {
     DMsg("No arguments supplied to DPrintF().");
  }
  return(NULL);
}

