/* ZX2LOGO: Convert a Spectrum loading screen into a Windows 95 loading screen
    Based on STRIPIFY
    Copyright (C) 1997,2000  John Elliott

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<time.h>

static unsigned char bmphdr[] = 
{
    'B','M',                /* Magic */
    0x36, 0xf8, 0x01, 0x00, /* File size */
    0x00, 0x00, 0x00, 0x00, /* Reserved */
    0x36, 0x04, 0x00, 0x00, /* Offset to data */
    0x28, 0x00, 0x00, 0x00, /* Length of header */
    0x40, 0x01, 0x00, 0x00, /* Width of bitmap */
    0x90, 0x01, 0x00, 0x00, /* Height of bitmap */
    0x01, 0x00,             /* Planes */
    0x08, 0x00,             /* Depth */
    0x00, 0x00, 0x00, 0x00, /* Compression */
    0x00, 0xf4, 0x01, 0x00, /* Image size */
    0xce, 0x0e, 0x00, 0x00, /* Xres */
    0xc4, 0x0e, 0x00, 0x00, /* Yres */
    0x00, 0x00, 0x00, 0x00, /* Used colours */
    0x10, 0x00, 0x00, 0x00, /* Important colours */
};

#define RGB(r,g,b) b, g, r, 0, 

static unsigned char palette[] = 
{
    RGB(0x00, 0x00, 0x00)   /* Normal */
    RGB(0x00, 0x00, 0xC0)
    RGB(0xC0, 0x00, 0x00)
    RGB(0xC0, 0x00, 0xC0)
    RGB(0x00, 0xC0, 0x00)
    RGB(0x00, 0xC0, 0xC0)
    RGB(0xC0, 0xC0, 0x00)
    RGB(0xC0, 0xC0, 0xC0)
    RGB(0x00, 0x00, 0x00)   /* Bright */
    RGB(0x00, 0x00, 0xFF)
    RGB(0xFF, 0x00, 0x00)
    RGB(0xFF, 0x00, 0xFF)
    RGB(0x00, 0xFF, 0x00)
    RGB(0x00, 0xFF, 0xFF)
    RGB(0xFF, 0xFF, 0x00)
    RGB(0xFF, 0xFF, 0xFF)
};

unsigned char screen[6912];

int point(int x, int y) /* Note that Y goes up from the bottom, both in
                         * Spectrum SCREEN$ and Windows BMPs */
{
    int x1 = x;
    int y1 = 191 - y;                   /* y1 = lines from the top */
    int y2 = (y1 / 8);
    int x2 = (x1 / 8);                  /* Attribute file position */
    int scroff;
    int clr;
    unsigned char v,m;

    scroff  = (2048 * (y1 >> 6)); y1 &= 0x3F;    /* Bits 6-7 of Y */ 
    scroff += (32   * (y1 >> 3)); y1 &= 0x07;    /* Bits 3-5 of Y */
    scroff += (256  * y1);                       /* Bits 0-2 of Y */
    scroff += (x1 >> 3); x1 &= 7;                /* Bits 7-3 of X */
    
    v = screen[scroff];
    m = 0x80;
    if (x1) m = m >> x1;
    v &= m;     /* V = 0 for paper, else ink */

    scroff = 6144 + (32 * y2) + x2; 

    if (v) clr = screen[scroff] & 7;
    else   clr = (screen[scroff] >> 3) & 7;

    if (screen[scroff] & 64) clr += 8;

    return clr;
}


void main(int argc, char **argv)
{
	FILE *fp, *fp2;
	long n;
	int fe, byt, c;
	
	if (argc < 3)
	{
		fprintf(stderr,"ZX2LOGO: Syntax is ZX2LOGO <source> <dest>\n\n"
					   "<source> is a Spectrum screen in SCREEN$ format\n"
					   "<dest>   is the BMP file to create.\n");
		exit(1);
	}
	fp  = fopen(argv[1], "rb");

	if (!fp)
	{
		perror(argv[1]);
		exit(1);
	}

	fp2 = fopen(argv[2], "wb");
	
	if (!fp2)
	{
		fclose(fp);
		perror(argv[2]);
		exit(1);
	}

    fe = 0;
    if (fread(screen, 1, 128, fp) < 128) fe = 1;
    else 
    {
        if (!memcmp(screen, "PLUS3DOS\032", 9))
        {
            if (fread(screen, 1, 6912, fp) < 6912) fe = 1;
        }
        else
        {
            if (fread(screen+128, 1, 6784, fp) < 6784) fe = 1;
        }
    }
    if (fe)
    {
        if (ferror(fp)) perror(argv[1]);
        else            fprintf(stderr,"%s: Not a Spectrum SCREEN$ file\n",
                                argv[1]);
        fclose(fp);
        fclose(fp2);
        exit(1);
    }
    /* Write out BMP header */
    fclose(fp);
    if (fwrite(bmphdr, 1, sizeof(bmphdr), fp2) < (int)sizeof(bmphdr))
    {
        perror(argv[2]);
        fclose(fp2);
        exit(1);
    }
    srand(time(NULL));
    /* Create palette */
    if (fwrite(palette, 1, sizeof(palette), fp2) < (int)sizeof(palette))
    {
        perror(argv[2]);
        fclose(fp2);
        exit(1);
    }

    for (n = 16; n < 256; n++)
    {
        byt = (rand() & 1); 

		if (byt)
		{
			fputc(0xFF, fp2);   /* Blue */
			fputc(0x00, fp2);
			fputc(0x00, fp2);
			fputc(0x00, fp2);
		}
		else
		{
			fputc(0x00, fp2);   /* Yellow */
			fputc(0xFF, fp2);
			fputc(0xFF, fp2);
			fputc(0x00, fp2);
		}
	}

    /* 400 screen lines */
  
	for (n = 0; n < 400; n++)
	{
		if (!(n & 1)) byt = (rand() % 240 + 16);

        /* Top/bottom border */
        if (n < 8 || n >= 392)
        {
            for (c = 0; c < 320; c++) fputc(byt, fp2);
            continue;
        }
        /* Remainder: 32 border pixels, then screen lines */
        for (c = 0; c < 32; c++) fputc(byt, fp2);
    
        for (c = 0; c < 256;c++) fputc(point(c, (n - 8)/2), fp2);

        for (c = 0; c < 32; c++) fputc(byt, fp2);       
 
	}
	fclose(fp2);
	exit(0);
}
