/*
    File: SetRes.c

    Description : Demo to show how to use the tms340class.library
                  You can set the resolution and display an 
                  raw image to the Director II board.
                  (This raw image is generated by the IFF2RAW
                   included with the EGS and stored as the egs:monitors/bootlogo)   
                  ...and don't blaim me for the fopen()/fread()/fclose()
                  unix trash, it uses more mem but is way fast to implement =:-)

    Legal:        You can use this code for what ever you want (e.g. datatype
                  viewer etc.). But the tms340class.library is ©1996 Jürgen Schober !
                  It _MUST_ _NOT_ be used in any comercial product without my permission !
                  (e.g. CyberGraphX® or what ever !)

    Author: Jürgen Schober
    Date: xx.1.96
    Last Modified: 6.2.96
*/
#include <pragmas/exec_pragmas.h>
#include <pragmas/BaseClass_pragmas.h>

#include <clib/exec_protos.h>
#include <clib/BaseClass_protos.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <tms340/BaseClass.h>

struct Library *ExpansionBase,*TMS340ClassBase;

#define TMS_A2410_CLASS "A2410"
#define TMS_DIR_II_CLASS "DirectorII"
#define TMS_TEST_CLASS "TestClass"
#define NON_INTERLACE 1
#define INTERLACE 2

struct Geometry
{
    UWORD HESYNC,HEBLNK,HSBLNK,HTOTAL;
    UWORD VESYNC,VEBLNK,VSBLNK,VTOTAL;
    UWORD DPYCTL;
};
TMSClassPtr DirectorIIClass;
TMSIORegPtr IORegs;

void SetRes(UWORD Width, UWORD Height, long Flag)
{
    struct Geometry Geometry;

/*
    If you get trouble with a stable display
    you should try to play around with
    the HSYNC (usaly ~90 (?)) and the HEBLNK
    (usaly ~149 on default D2 resolution (MULTISYNC/910/576))
    But because the Director 2 has a real low pixel bandwith
    I use it at 450x(what_ever)x32 and these values generate
    a stable picture on these low resoultions
 */
    Geometry.HESYNC = 30;
    Geometry.HEBLNK = Geometry.HESYNC + 20;
    Geometry.HSBLNK = Geometry.HEBLNK + Width;
    Geometry.HTOTAL = Geometry.HSBLNK + 10;

    Geometry.VESYNC = 9;
    Geometry.VEBLNK = Geometry.VESYNC + 15;
    Geometry.VSBLNK = Geometry.VEBLNK + (Height / Flag);
    Geometry.VTOTAL = Geometry.VSBLNK + 5;

    WriteTMSReg(DirectorIIClass,IORegs->HESYNC,Geometry.HESYNC);
    WriteTMSReg(DirectorIIClass,IORegs->HEBLNK,Geometry.HEBLNK);
    WriteTMSReg(DirectorIIClass,IORegs->HSBLNK,Geometry.HSBLNK);
    WriteTMSReg(DirectorIIClass,IORegs->HTOTAL,Geometry.HTOTAL);

    WriteTMSReg(DirectorIIClass,IORegs->VESYNC,Geometry.VESYNC);
    WriteTMSReg(DirectorIIClass,IORegs->VEBLNK,Geometry.VEBLNK);
    WriteTMSReg(DirectorIIClass,IORegs->VSBLNK,Geometry.VSBLNK);
    WriteTMSReg(DirectorIIClass,IORegs->VTOTAL,Geometry.VTOTAL);
    if (Flag == 1)
    {
        WriteTMSReg(DirectorIIClass,IORegs->DPYCTL,0xd047);
    }
    else if (Flag == 2)
    {
        WriteTMSReg(DirectorIIClass,IORegs->DPYCTL,0x9047);
    }
}

/* 
    The File header of the RAW 24 Image format
 */
struct hd_RAW24
{
    UBYTE key[4];
    UWORD width;
    UWORD height;
};

void main(int argc, char **argv)
{
    ULONG w = 0,h = 0,x0,y0;
    STRPTR Name;
    FILE *fp;
    ULONG *pic,size,i;
    struct hd_RAW24 hd_raw24;
    ULONG mr = 0xFF000000,mb = 0x0000FF00,mg = 0x00FF0000, red,blue;
  
    switch (argc)  
    {
        case 2 :
            Name = (argv[1]);   // only a image name is given, res is still the same
            break;
        case 3 :
            w = atol(argv[1]);  // switch resolution, image stays the same
            h = atol(argv[2]);
            Name = 0L;
            break;
        case 4 :
            w = atol(argv[1]);  // both, image and resolution is changend
            h = atol(argv[2]);
            Name = argv[3];
            break;
        default:                // wrong parameter
            puts("Usage: SetD2Res Width Height [Lace|Nonlace]");
            exit(20);

    }
    if (TMS340ClassBase = (struct Library*)OpenLibrary("tms340class.library",0L))
    {
        if (DirectorIIClass = ObtainTMSClass(TMS_DIR_II_CLASS))
        {
            IORegs = DirectorIIClass->TMSBoardInfo->IORegister;
            if ( w && h )
                SetRes(w,h,NON_INTERLACE);

            if (Name)
            {
                size = 0x100000; // 1 MB
                if (pic = AllocVec(size,MEMF_CLEAR))
                {
                    /* Clear 4 MB Director II Memory, address is gsp bitaddr. !*/
                    WriteTMSDataArray(DirectorIIClass,pic,0x0000000,size);
                    WriteTMSDataArray(DirectorIIClass,pic,0x0800000,size);
                    WriteTMSDataArray(DirectorIIClass,pic,0x1000000,size);
                    WriteTMSDataArray(DirectorIIClass,pic,0x1800000,size);
                    FreeVec(pic);
                }
                if (fp = fopen(Name,"r"))
                {
                    /* Read header and check if "RW24" image */
                    fread(&hd_raw24,sizeof(struct hd_RAW24),1,fp);
                    if (strncmp(hd_raw24.key,"RW24",4) == NULL)
                    {              
                        printf("%s, Head : %c%c%c%c , Size : %dx%d\n",Name,hd_raw24.key[0],hd_raw24.key[1],hd_raw24.key[2],hd_raw24.key[3],
                                                                  hd_raw24.width,hd_raw24.height);
                        /* get size info */
                        size = hd_raw24.width * hd_raw24.height;
                        /* allocate memory */
                        if (pic = (ULONG*)AllocVec(size * 4, 0))
                        {
                            /* read the image */
                            fread(pic,sizeof(ULONG),size,fp);
                            /* convert RGBA -> BGRA */
                            for ( i = 0; i < size; i++)
                            {
                                red    = (pic[i] & mr) >> 16;
                                blue   = (pic[i] & mb) << 16;
                                pic[i] = blue | (pic[i] & mg) | red ; 
                            }
                            /* center the image */
                            x0 = (w > hd_raw24.width)  ? (w - hd_raw24.width)  / 2 : 0;
                            y0 = (h > hd_raw24.height) ? (h - hd_raw24.height) / 2 : 0;
                            /* Blit the image into the D2 Memory */
                            WriteTMSPixelXY(DirectorIIClass,
                                           pic,hd_raw24.width,
                                           0,0,
                                           0x0L,910,
                                           x0,y0,
                                           hd_raw24.width,hd_raw24.height);

                            /* Free the Image memory */
                            FreeVec(pic);
                        }
                    }
                    /* Close the file */
                    fclose(fp);
                }
            }
        }
        /* close the class lib */
        CloseLibrary(TMS340ClassBase);   
    }
    /* and go out again */
    exit(0);
}

