/* Copyright 1991 by Michael Jansson, All rights reserved.

 NAME:  BMore
 USAGE: BMore [-v][-q] <font name> <width> <height> <file name>
 VERSION: 1.1

This is a small benchmark program that will display a text file as fast
as it can. It uses both normal amiga bitmap fonts and the new vfont vector
fonts.

[See comments about the -q flag in the rotate.c file]

*/


#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/vfontlib.pro>
#include <pragmas/dos.h>
#include <pragmas/exec.h>
#include <pragmas/intuition.h>
#include <pragmas/graphics.h>
#include <pragmas/vfontlib.pra>
#include <vfont/curve.h>
#include <vfont/vfont.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>

/* Some macros. (It's done this way to improve the readability of the code). */
#define MyPutS(str)     Write(Output(), str "\n", (long)strlen(str)+1L)

/* A description of the font that we are interested in. */
TextVAttr tattr = {
    (UBYTE *)"fixwire.vfont",   /* The name of the class. */
    32,                         /* The height */
    1,                          /* It is a vector font. */
    FS_NORMAL,                  /* The style. */
    FPF_DESIGNED|FPF_DISKFONT,  /* The flags. */
    (UBYTE *)"John",            /* Our name for this font. */
    0,                          /* X Size. */
    VFB_EXCLUSIVE|VFB_ANYSIZE,  /* VFlags. */
    0                           /* Desired File format. */
};


/* Some intuition structure used when opening the screen and the window. */

#define ProgramName (UBYTE *)"BMore v1.1 - Copyright 1991 by Michael Jansson"
#define width 640L
#define height 512L			/* Change this to 400 for NTSC. */

struct NewScreen newscreen = {
    0,0,width,height,1,         /* Screen dimensions. */
    0,-1,                       /* Pen colors. */
    LACE|HIRES,                 /* View modes. */
    CUSTOMSCREEN,               /* Screen type. */
    NULL,                       /* Default screen font (none). */
    ProgramName,                /* Screen title. */
    NULL,                       /* Gadgets (none). */
    NULL                        /* CustomBitMap (none). */
};

struct NewWindow newwindow = {
    0,0,width,height,           /* Window dimensions. */
    0,-1,                       /* Pen colors. */
    0UL,                        /* IDCMPFlags (none). */
        SIMPLE_REFRESH |        /* Flags. (We want a really simple window). */
        NOCAREREFRESH |
        BORDERLESS,
    NULL,                       /* Gadgets. (none). */
    NULL,                       /* Check mark. (none). */
    ProgramName,                /* Title. */
    NULL,                       /* Screen (set it to our screen when it is open). */
    NULL,                       /* BitMap. (none). */
    0,0,width,height,           /* Min/Max dimensions. */
    CUSTOMSCREEN                /* Window type. */
};

/* Library names. */
#define INTUITION   (UBYTE *)"intuition.library"
#define GRAPHICS    (UBYTE *)"graphics.library"
#define VFONTS      (UBYTE *)"vfont.library"

#define AREABUFFSIZE   2000L
#define AREABUFFSIZE5 10000L

/* Global data. */
UBYTE *myBuffer;
struct AreaInfo myArea;
struct TmpRas myTmpRas;
BOOL vector_flg = FALSE;
long size = 0;

/* Global data that is allocated/opened. */
struct Library *IntuitionBase = NULL;
struct Library *vFontBase = NULL;
struct Library *GfxBase = NULL;
struct Screen *screen = NULL;
struct Window *window = NULL;
struct TextFont *font = NULL;
PLANEPTR myPlane = NULL;
UBYTE *buffer = NULL;
VFont *vfont = NULL;
BPTR file = 0L;


void
_abort(void)
{
    if (file)
        Close(file);
	if (buffer)
		FreeMem(buffer, size);
	if (vector_flg) {
	    if (vfont)
    	    CloseVFont(vfont);
	} else {
	    if (font)
    	    CloseFont(font);
	}
	if (myPlane)
		FreeRaster(myPlane, width, height);
    if (myBuffer)
        FreeMem(myBuffer, AREABUFFSIZE5);
    if (window)
        CloseWindow(window);
	if (screen)
		CloseScreen(screen);
    if (vFontBase)
        CloseLibrary(vFontBase);
    if (IntuitionBase)
        CloseLibrary(IntuitionBase);
    if (GfxBase)
        CloseLibrary(GfxBase);
    exit();
}

void
ClearMem(void *data, int size)
{
    while(size)
        ((char *)data)[--size] = '\0';
}

void
main(int argc, char **argv)
{
	struct RastPort *RPort;
    LONG t1[3], t2[3];
    char line[256];
    long Args = 0;
    long row;
    long tot = 0;
	long ysize;
	long count = 0;
    BOOL quick_flg = FALSE;
    long i;

    /* Process the CLI parameters. */
    if (argc<4) {
        MyPutS("Usage: bmore [-v][-q] font xsize ysize filename");
        return;
    }
    while (argv[++Args][0]=='-') {
        if (tolower(argv[Args][1])=='v')
            vector_flg = TRUE;
        if (tolower(argv[Args][1])=='q')
            quick_flg = TRUE;
    }
    
    /* Set up the requirements for the font. */
    tattr.Name = (UBYTE *)argv[Args++];
    tattr.XSize = atoi(argv[Args++]);
    tattr.YSize = atoi(argv[Args++]);
    if ((tattr.XSize<0) || (tattr.YSize<=0)) {
        MyPutS("Invalid font size.");
        _abort();
    }

    /* Open the needed libraries. */
    if (!(IntuitionBase = OpenLibrary(INTUITION, 0L))
    || !(GfxBase = OpenLibrary(GRAPHICS, 0L))
    || !(vFontBase = OpenLibrary(VFONTS, 0L))) {
        MyPutS("Can't open the vfont libarary.");
        _abort();
    }

    /* Open the file. */
    if ((file = Open((UBYTE *)argv[Args], (long)MODE_OLDFILE))==NULL) {
        MyPutS("Can't open the that file.");
        _abort();
    }
    Seek(file, 0L, (long)OFFSET_END);
    size = Seek(file, 0L, (long)OFFSET_BEGINNING);
    if (!(buffer=AllocMem(size, 0L))) {
        MyPutS("File to big to be loaded at once!");
        _abort();
    }
    if (size!=Read(file, buffer, size)) {
        MyPutS("DOS error while reading file.");
        _abort();
    }
    MyPutS("Text file loaded!");
    Close(file);
    file = 0L;

    /* Book keep the time. */
    DateStamp(t1);

    /* Open the font. */
    if (vector_flg) {
        /* Open a vector font. */
        if ((vfont = OpenVFont(&tattr))==NULL) {
            MyPutS("Didn't manage to open the font.");
            _abort();
        }
    } else {
        /* Open a font that is both a vector font and a true amiga bitmap font. */
        if ((font = OpenBFont(&tattr))==NULL) {
            MyPutS("Didn't manage to open the font.");
            _abort();
        }
    }

    DateStamp(t2);
    printf("Time to load the font: %ld msec\n",(long)(t2[2]-t1[2])*20);

    /* Open a screen. */
    if (!(screen = OpenScreen(&newscreen))) {
        MyPutS("Couldn't open screen.");
        _abort();
    }

    if (quick_flg)
     	RPort = &screen->RastPort;
    else {

        /* Open a window. */
        newwindow.Screen = screen;
        if (!(window=OpenWindow(&newwindow))) {
            MyPutS("Failed to open a window.");
            _abort();
        }
 	    RPort = window->RPort;
    }

    SetDrMd(RPort, (long)JAM1);


	/* Add a TmpRas. */
	if (!(myPlane=AllocRaster(width, height)))
		_abort();
	InitTmpRas(&myTmpRas, myPlane, (long)RASSIZE(width, height));
	RPort->TmpRas = &myTmpRas;

	/* Add an AreaInfo. */
    if (!(myBuffer=AllocMem(AREABUFFSIZE5, 0L)))
        _abort();
	InitArea(&myArea, myBuffer, AREABUFFSIZE);
	RPort->AreaInfo = &myArea;

    /* Let the library know that it should use this font in our rastport. */
	if (vector_flg) {
		SetVFont(RPort, vfont);
		ysize = vfont->YSize;
	} else {
		SetFont(RPort, font);
		ysize = font->tf_YSize;
	}

    /* Book keep the time. */
    DateStamp(t1);

    SetAPen(RPort, 1L);
    SetDrMd(RPort, (long)JAM1);
    ScreenToFront(screen);
	row = ysize+12;
    while (count!=size) {
        i = 0;
        do {
            line[i++] = buffer[count++];
        } while (line[i-1]!='\n' && i<256 && count<size);
        Move (RPort, 4L, row);
/*
    VText is a function that will use the vector font that is assigned to 
    the given rastport, or else use the default TextFont font if no
    vector font is given.
*/
        VText(RPort, (UBYTE *)line, i-1);
        tot += i;
        row += ysize;
        if (row>=500) {
            SetRast(RPort, 0L); 
            row = ysize+12L;
        }
		Chk_Abort();
    }

    /* Report the elapsed time. */
    DateStamp(t2);
    printf("Chars/sec %ld\n",(long)tot/((t2[1]-t1[1])*60+(t2[2]-t1[2])/50));

	_abort();
}
