view exporters.pde @ 120:55b0a77af602

Clean up the format import code a bit.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 09 Jul 2018 17:44:47 +0300
parents 44a07b1c620d
children 25a29d29ee6a
line wrap: on
line source

//
// machine definitions
// source writer and other export/import functions
// remember hexdump -C !
//
String g_formatname, g_formatext;
int g_dataoffs;
int[] g_grids = new int[16];
int OLD = 0;
int NEW = 1;
int g_gridmode = OLD;


void mpCopyByte(byte[] fdata, int moffs, int toffs)
{
    g_map[moffs    ] = byte((fdata[toffs] & 128) >> 7);
    g_map[moffs + 1] = byte((fdata[toffs] & 64) >> 6);
    g_map[moffs + 2] = byte((fdata[toffs] & 32) >> 5);
    g_map[moffs + 3] = byte((fdata[toffs] & 16) >> 4);
    g_map[moffs + 4] = byte((fdata[toffs] & 8) >> 3);
    g_map[moffs + 5] = byte((fdata[toffs] & 4) >> 2);
    g_map[moffs + 6] = byte((fdata[toffs] & 2) >> 1);
    g_map[moffs + 7] = byte( fdata[toffs] & 1);
}


void mpSetDataOffs(int offs)
{
    g_dataoffs = offs;
}


void mpWriteByte(int bb)
{
    g_template[g_dataoffs++] = byte(bb);
}


void mpLoadTemplate(String fname)
{
    g_template = mpLoadBinaryFile("templates/" + fname);
}


boolean mpImportFormat(byte[] fdata)
{
    int x, y, x2, y2, y3, head, xx, yy, yp, ad, valu;
    int p1, p2, p3;

    head = 0;

    if (machine == SPECTRUM) //SCR=SCREEN$
    {
        // 32*24*8 bytes of bitmap
        // 32*24 bytes of attributes
        if (fdata.length < 6912) {
            return false;
        }
        for (y = 0; y < 3; y++)
        for (y2 = 0; y2 < 8; y2++)
        for (yy = 0; yy < 8; yy++)
        for (x = 0; x < 32; x++)
        {
            yp = y * 64 + yy * 8 + y2;
            ad = 1024 + yp * 256 + x * 8;
            mpCopyByte(fdata, ad, head);
            head++;
        }

        for (y = 0; y < 24; y++)
        for (x = 0; x < 32; x++)
        {
            ad = 65536 + x + y * (32 * 8);
            valu = fdata[head];
            int ink = valu & 7;
            int pap = valu & 56;
            pap = pap >> 3;
            int bri = valu & 64;
            bri = bri >> 6;
            ink = ink + bri * 8;
            pap = pap + bri * 8;
            if (pap == 8) {
                pap = 0;
            }
            for (y2 = 0; y2 <= 7; y2++)
            {
                g_map[ad + y2 * 32] = byte(ink);
                g_map[ad + y2 * 32 + MX * MY * 8] = byte(pap);
            }
            head++;
        }
    }
    else
    if (machine == C64) {
        //0x0002->bitmap
        //0x1f42->colormap
        //0x232a=border (take the lower nybble)
        if (fdata.length < 9006) {
            return false;
        }
        if (fdata.length >= 0x232a) {
            g_map[0] = byte(fdata[0x232a] & 0x0f);
        }
        for (y = 0; y < 25; y++)
        for (x = 0; x < 40; x++)
        for (y2 = 0; y2 <= 7; y2++)
        {
            head = 2 + x * 8 + y * (40 * 8) + y2;
            ad = 1024 + x * 8 + y * (320 * 8) + y2 * 320;
            mpCopyByte(fdata, ad, head);
            p1 = fdata[0x1f42 + x + y * 40] & 0x0f;
            p2 = fdata[0x1f42 + x + y * 40] & 0xf0;
            p2 = p2 >> 4;
            g_map[65536 + x + y * 40 * 8 + y2 * 40] = byte(p2);
            g_map[65536 + MX * MY * 8 + x + y * 40 * 8 + y2 * 40] = byte(p1);
        }
    }
    else
    if (machine == PLUS4) { // Botticelli
        //g.hires.prg = botticelli
        //2 - luminance 40*25
        //1026 - colors 40*25
        //2050 - bitmappi 40*25*8
        if (fdata.length < 10050) {
            return false;
        }
        int l1, l2;
        for (y = 0; y < 25; y++)
        for (x = 0; x < 40; x++)
        for (y2 = 0; y2 <= 7; y2++)
        {
            head = 2050 + x * 8 + y * (40 * 8) + y2;
            ad = 1024 + x * 8 + y * (320 * 8) + y2 * 320;
            mpCopyByte(fdata, ad, head);

            p1 = fdata[1026 + x + y * 40] & 0x0f;
            p2 = fdata[1026 + x + y * 40] & 0xf0;
            p2 = p2 >> 4;
            l1 = fdata[2 + x + y * 40] & 0x0f;
            l2 = fdata[2 + x + y * 40] & 0xf0;
            l2 = l2 >> 4;
            g_map[65536 + x + y * 40 * 8 + y2 * 40] = byte(convertluminance(l1, p2));
            g_map[65536 + MX * MY * 8 + x + y * 40 * 8 + y2 * 40] = byte(convertluminance(l2, p1));
        }
    }
    else
    if (machine == PLUS4M) { // Multi Botticelli
        //m.multi.prg = multi botticelli
        //2- lumins 40*25
        //1024 - bäkki1
        //1025 - bäkki2
        //1026 - colors 40*25
        //2050 - bitmap 40*25*8
        if (fdata.length < 10050) {
            return false;
        }
        int l1, l2;
        for (y = 0; y < 25; y++)
        for (x = 0; x < 40; x++)
        for (y2 = 0; y2 <= 7; y2++)
        {
            head = 2050 + x * 8 + y * (40 * 8) + y2;
            ad = 1024 + x * 8 + y * (320 * 8) + y2 * 320;
            mpCopyByte(fdata, ad, head);

            p1 = fdata[1026 + x + y * 40] & 0x0f;
            p2 = fdata[1026 + x + y * 40] & 0xf0;
            p2 = p2 >> 4;
            l1 = fdata[2 + x + y * 40] & 0x0f;
            l2 = fdata[2 + x + y * 40] & 0xf0;
            l2 = l2 >> 4;
            g_map[65536 + x + y * 40 + 1000] = byte(convertluminance(l1, p2));
            g_map[65536 + x + y * 40 + 0000] = byte(convertluminance(l2, p1));
        }

        p1 = int(fdata[1025]) & 0xf0;
        l1 = int(fdata[1025]) & 0x0f;
        p1 = p1 >> 4;
        g_map[1] = byte(convertluminance(l1, p1));
        p1 = int(fdata[1024]) & 0xf0;
        l1 = int(fdata[1024]) & 0x0f;
        p1 = p1 >> 4;
        g_map[2] = byte(convertluminance(l1, p1));
    }
    else
    if (machine == C64M) { //advanced art studio
        //adv. art studio (=multicolor) 10018 bytes
        //0x0002 bitmap (40*25*8)
        //0x1f42 colors1 (40*25)
        //0x232a border
        //0x232b background
        //0x233a colors2 (40*25)
        if (fdata.length < 10018) {
            return false;
        }
        for (y = 0; y < 25; y++)
        for (x = 0; x < 40; x++)
        for (y2 = 0; y2 < 8; y2++)
        {
            ad = 1024 + x * 8 + y * (320 * 8) + y2 * 320;

            head = 2 + x * 8 + y * (40 * 8) + y2;
            mpCopyByte(fdata, ad, head);

            p1 = fdata[0x1f42 + x + y * 40] & 0x0f;
            p2 = (fdata[0x1f42 + x + y * 40] >> 4) & 0x0f;
            p3 = fdata[0x233a + x + y * 40] & 0x0f;

            g_map[65536 + x + y * 40] = byte(p1);
            g_map[65536 + x + y * 40 + 1000] = byte(p2);
            g_map[65536 + x + y * 40 + 2000] = byte(p3);
        }
        g_map[0] = byte(fdata[0x232a] & 0x0f); //bord
        g_map[1] = byte(fdata[0x232b] & 0x0f); //baku
    }
    else
    if (machine == MSX) { // sc2
        // 7=bitmap 32*24*8
        // 7+(32*24*8)=colormap 32*24
        if (fdata.length < 14343) {
            return false;
        }
        for (y = 0; y < 24; y++)
        for (x = 0; x < 32; x++)
        for (y2 = 0; y2 <= 7; y2++)
        {
            head = 7 + x * 8 + y * (32 * 8) + y2;
            ad = 1024 + x * 8 + y * (256 * 8) + y2 * 256;
            mpCopyByte(fdata, ad, head);
            p1 = fdata[(8199) + x * 8 + ((y * 8 * 32) + y2)] & 0x0f;
            p2 = fdata[(8199) + x * 8 + ((y * 8 * 32) + y2)] & 0xf0;
            p2 = p2 >> 4;
            if (p1 == 0) {
                p1 = 1;
            }
            if (p2 == 0) {
                p2 = 1;
            }
            g_map[65536 + x + y * 32 * 8 + y2 * 32] = byte(p2);
            g_map[65536 + MX * MY * 8 + x + y * 32 * 8 + y2 * 32] = byte(p1);
        }
    }
    else
    if (machine == CPC) { // a studio?
        return false;
    }

    consistency();
    refresh();
    g_boxreconstruct = 2;
    return true;
}


byte[] mpExportFormat(int subformat)
{
    int val1, val2, val3;
    int y, y2, yy, x, yp, xp, ad, valu, valu2, bri;

    if (machine == PLUS4) { // botticelli hires
        mpLoadTemplate("g.hires.prg");
        mpSetDataOffs(0x02);
        mpExportColorData(40, 25, 65536, 5); //lumis
        mpSetDataOffs(1026);
        mpExportColorData(40, 25, 65536, 4); //colors
        mpSetDataOffs(2050);
        mpExportBitmapData(40, 25);
    }
    else
    if (machine == PLUS4M) { // multi botticelli multicolor
        mpLoadTemplate("m.multi.prg");
        val2 = getpluscolor(int(g_map[1]));
        val1 = getplusluminance(int(g_map[1]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(1025);
        mpWriteByte(val3);
        val2 = getpluscolor(int(g_map[2]));
        val1 = getplusluminance(int(g_map[2]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(1024);
        mpWriteByte(val3);
        mpSetDataOffs(1026);
        mpExportColorData(40, 25, 65536, 6); //colors
        mpSetDataOffs(2);
        mpExportColorData(40, 25, 65536, 7); //lumis
        mpSetDataOffs(2050);
        mpExportBitmapData(40, 25);
    }
    else
    if (machine == C64) {
        mpLoadTemplate("hires.art");
        mpSetDataOffs(2);
        mpExportBitmapData(40, 25);
        mpSetDataOffs(0x1f42);
        mpExportColorData(40, 25, 65536, 0);
        mpSetDataOffs(0x232a);
        mpWriteByte(g_map[0]);
    }
    else
    if (machine == C64M) {
        if (subformat == 0)
        {
            // Advanced Art Studio
            mpLoadTemplate("multic.ocp");
            mpSetDataOffs(2);
            mpExportBitmapData(40, 25);
            mpSetDataOffs(0x1f42);
            mpExportColorData(40, 25, 65536, 1);
            mpSetDataOffs(0x233a);
            mpExportColorData(40, 25, 65536 + 2000, 2);
            mpSetDataOffs(0x232a);
            mpWriteByte(g_map[0]);
            mpSetDataOffs(0x232b);
            mpWriteByte(g_map[1]);
        }
        else
        {
            // Koala Painter
            mpLoadTemplate("multic.kla");
            mpSetDataOffs(2);
            mpExportBitmapData(40, 25);
            mpSetDataOffs(0x1f42);
            mpExportColorData(40, 25, 65536, 1);
            mpSetDataOffs(0x232a);
            mpExportColorData(40, 25, 65536 + 2000, 2);
            mpSetDataOffs(0x2712);
            mpWriteByte(g_map[1] & 0x0f);
        }
    }
    else
    if (machine == MSX) {
        mpLoadTemplate("msx-screen2.sc2");
        mpSetDataOffs(7);
        mpExportBitmapData(32, 24);
        mpSetDataOffs(7 + (32 * 24 * 8) + 768 + 1280);
        mpExportColorData(32, 24, 65536, 3); //there's an exception for msx-style
    }
    else
    if (machine == SPECTRUM) {
        mpLoadTemplate("zx-screen.scr");
        mpSetDataOffs(0);
        for (y = 0; y < 3; y++)
        for (y2 = 0; y2 < 8; y2++)
        for (yy = 0; yy < 8; yy++)
        for (x = 0; x < 32; x++)
        {
            yp = y * 64 + yy * 8 + y2;
            ad = 1024 + yp * 256 + x * 8;

            valu = g_map[ad + 0] * 128 +
                   g_map[ad + 1] * 64 +
                   g_map[ad + 2] * 32 +
                   g_map[ad + 3] * 16 +
                   g_map[ad + 4] * 8 +
                   g_map[ad + 5] * 4 +
                   g_map[ad + 6] * 2 +
                   g_map[ad + 7] * 1;

            mpWriteByte(valu);
        }

        for (y = 0; y < 24; y++)
        for (x = 0; x <= 31; x++)
        {
            ad = 65536 + x + y * 256;
            valu = int(g_map[ad]);
            valu2 = int(g_map[ad + MX * MY * 8]);
            bri = 0;
            if (valu >= 8) {
                bri = 1;
                valu = valu - 8;
                valu2 = valu2 - 8;
                if (valu2 <= 0) {
                    valu2 = 0;
                }
            }
            if (bri == 1) {
                valu += 64;
            }
            mpWriteByte(valu + valu2 * 8);
        }
    }
    else
        return null;

    return fdata;
}


byte[] mpExportMachinePRG(boolean sorsa)
{
    // any common text headers
    String src = ";machine=" + str(machine) + " (" + g_name + ")\n";
    String bsrc = "";

    if (machine == C64) { //C64 HIRES

        mpLoadTemplate("c64show.prg");
        mpSetDataOffs(0x0227);
        bsrc = mpExportBitmapData(40, 25);

        mpSetDataOffs(0x2167);
        mpWriteByte(g_map[0]); //=border
        mpSetDataOffs(0x2168);
        mpWriteByte(g_map[1]); //=background mutta ei tarvita
        mpSetDataOffs(0x2169);
        src += "; The following two first values are border and background\n";
        src += mpExportColorData(40, 25, 65536, 0);

        //c64show.prg
        //offsets
        //0x0227->bitmappi (40x25 x 8 bytee)
        //0x2167:borderi väri
        //0x2169->värikartta (40x25 bytee, nyppelit foreg/backg)
    }
    else
    if (machine == C64M) { //C64 MULTICOLOR

        mpLoadTemplate("c64mshow.prg");
        mpSetDataOffs(0x0239);
        bsrc = mpExportBitmapData(40, 25);

        // first color information
        mpSetDataOffs(0x2179);
        mpWriteByte(g_map[0]);
        mpSetDataOffs(0x217A);
        mpWriteByte(g_map[1]);
        mpSetDataOffs(0x217B);
        src += "; The following two first values are border and background\n";
        src += mpExportColorData(40, 25, 65536, 1);

        // second color information
        mpSetDataOffs(0x2563);
        src += "; The following goes to $D800 onwards\n";
        src += mpExportColorData(40, 25, 65536 + 2000, 2);

        //c64 multicolor
        //offsets
        //0x0239->bitmappi (40x25 x 8 bytee)
        //0x2179:borderi väri
        //0x217A:bäkkis väri
        //0x217B->värikartta 1 (40x25 bytee, nyppelit foreg/backg ilmeisesti)
        //0x2563->värikartta 2 (40x25 bytee, nyppeli 3-väri nepan osoitteessa $d800-)
    }
    else
    if (machine == PLUS4M) { //PLUS4 MULTICOLOR
        mpLoadTemplate("showpfourm.prg");
        src += "  .global _bitmap\n";
        src += "  .global _color1\n";
        src += "  .global _color2\n";
        src += "  .global _border\n";
        src += "  .global _back1\n";
        src += "  .global _back2\n";
        src += "_bitmap:\n";
        mpSetDataOffs(0x013e);
        bsrc = mpExportBitmapData(40, 25);
        src += "_border:\n";
        val1 = getpluscolor(int(g_map[0]));
        val2 = getplusluminance(int(g_map[0]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(0x207e);
        mpWriteByte(val3);
        src += "  .byte " + val3 +"\n";
        src += "_back1:\n";
        val1 = getpluscolor(int(g_map[1]));
        val2 = getplusluminance(int(g_map[1]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(0x207f);
        mpWriteByte(val3);
        src += "  .byte " + val3 +"\n";
        src += "_back2:\n";
        val1 = getpluscolor(int(g_map[2]));
        val2 = getplusluminance(int(g_map[2]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(0x2080);
        mpWriteByte(val3);
        src += "  .byte " + val3 +"\n";
        src += "_color1:\n";
        mpSetDataOffs(0x2081);
        src += mpExportColorData(40, 25, 65536, 6);
        src += "_color2:\n";
        mpSetDataOffs(0x2469);
        src += mpExportColorData(40, 25, 65536, 7);
        //plus4 multic
        //0x013e bitmap (40 x 25 x 8)
        //0x207e border
        //0x207f background 1
        //0x2080 background 2
        //0x2081 colors (40 x 25)
        //0x2469 luminance (40 x 25)
    }
    else
    if (machine == PLUS4) { // Plus 4 hires
        mpLoadTemplate("showpfour.prg");
        src += "  .global _bitmap\n";
        src += "  .global _color\n";
        src += "  .global _lumi\n";
        src += "  .global _border\n";
        src += "_bitmap:\n";
        mpSetDataOffs(0x0137);
        bsrc = mpExportBitmapData(40, 25);
        val1 = getpluscolor(int(g_map[0]));
        val2 = getplusluminance(int(g_map[0]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(0x2077);
        mpWriteByte(val3); //border

        mpSetDataOffs(0x2078);
        src += mpExportColorData(40, 25, 65536, 4); //colors
        mpSetDataOffs(0x2460);
        src += mpExportColorData(40, 25, 65536, 5); //lumis
        //plus4 hires
        //0x0137   bitmap (40 x 25 x 8)
        //0x2077   borderi
        //0x2078   colors (40 x 25)
        //0x2460   luminance (40 x 25)
    }
    else
    if (machine == MSX) { // MSX
        mpLoadTemplate("msxshow.com");
        mpSetDataOffs(0x00f9);
        src += "\t.globl _nimi1,_nimi2\n";
        src += "\t.area _CODE\n";
        src += "_nimi1:\n";
        bsrc = mpExportBitmapData(32, 24);
        mpSetDataOffs(0x18f9);
        //mpWriteByte(g_map[1]); //backg
        //src += "; The first following value is background\n";
        src += "_nimi2:\n";
        src += mpExportColorData(32, 24, 65536, 3); //there's an exception for msx-style
        //msx comm
        //0x00f9 bitmap (32x24 x 8 bytes)
        //0x18f9 background color
        //0x18fa colors (32*24 bytes)
    }
    else
    if (machine == SPECTRUM) { // ZX Spectrum

        //would need some cleaning up

        //  src += "  .area  _DATA\n";
        //  src += "  .globl _taustakuva\n\n";
        //  src += "_taustakuva:\n";
        mpLoadTemplate("specshow.tap");

        int checksum = 0xc9;
        for (y = 0x1d24; y <= 0x1d3d; y++) { //1d3e
            checksum = checksum ^ int(g_template[y]);
        }

        //TAP requires fiddling with the checksum
        //println("Checksum:"+hex(checksum,2));
        mpSetDataOffs(0x0223);
        src += ".byte " + (str(g_map[0])) + " ;border\n";
        mpWriteByte(g_map[0]);
        checksum = checksum ^ int(g_map[0]);

        for (int y = 0; y <= 2; y++)
        for (int y2 = 0; y2 <= 7; y2++)
        for (int yy = 0; yy <= 7; yy++)
        {
            src += ".byte ";
            for (int x = 0; x <= 31; x++)
            {
                int yp = y * 64 + yy * 8 + y2,
                    ad = 1024 + yp * 256 + x * 8,
                    valu = g_map[ad + 0] * 128 + g_map[ad + 1] * 64 + g_map[ad + 2] * 32 + g_map[ad + 3] * 16 + g_map[ad + 4] * 8 + g_map[ad + 5] * 4 + g_map[ad + 6] * 2 + g_map[ad + 7] * 1;

                src += str(valu);
                mpWriteByte(valu);
                checksum = checksum ^ int(valu);
                if (x <= 30) {
                    src += ",";
                }
            }
            src += "\n";
        }

        src += "; attributes\n";
        for (int y = 0; y < 24; y++)
        {
            src += ".byte ";
            for (int x = 0; x < 32; x++)
            {
                int ad = 65536 + x + y * 256,
                    valu = int(g_map[ad]),
                    valu2 = int(g_map[ad + MX * MY * 8]),
                    bri = 0;

                if (valu >= 8)
                {
                    bri = 1;
                    valu = valu - 8;
                    valu2 = valu2 - 8;
                    if (valu2 <= 0) {
                        valu2 = 0;
                    }
                }
                if (bri == 1) {
                    valu = valu + 64;
                }

                src += str(valu + valu2 * 8);
                mpWriteByte(valu + valu2 * 8);
                checksum = checksum ^ int(valu + valu2 * 8);
                if (x <= 30) {
                    src += ",";
                }
            }
            src += "\n";
        }
        //println("checksum:"+hex(checksum,2));
        mpSetDataOffs(0x1d3e);
        mpWriteByte(int(checksum));
    }
    else
    if (machine == CPC) {
        int val1, val2, val3, valu;
        mpLoadTemplate("cpc-mode0.bin");

        mpSetDataOffs(69); //bitmap offset
        bsrc = mpExportBitmapData_CPC(160, 200);
        mpSetDataOffs(16453);
        src += ";palette\n";
        src += ".byte ";

        //fixed # of palette entries, just trying to be generic
        for (int i = 0; i < g_maxcolors; i++)
        {
            val1 = int(g_g[i] / (256 / g_palsteps));
            val2 = int(g_r[i] / (256 / g_palsteps));
            val3 = int(g_b[i] / (256 / g_palsteps));

            mpWriteByte(val1 * 9 + val2 * 3 + val3);
            src += str(val1 * 9 + val2 * 3 + val3);
            if (i < g_maxcolors - 1) {
                src += ",";
            }
        }

        valu = int(g_map[0]);
        val1 = int(g_g[valu] / (256 / g_palsteps));
        val2 = int(g_r[valu] / (256 / g_palsteps));
        val3 = int(g_b[valu] / (256 / g_palsteps));

        src += "\n";
        src += ";border\n";
        src += ".byte ";

        mpSetDataOffs(16469);

        mpWriteByte(val1 * 9 + val2 * 3 + val3);
        src += str(val1 * 9 + val2 * 3 + val3);
        //cpc
        //69    bitmap 16384 bytes
        //16453 palette 16 bytes (0..26)
        //16469 border color (0..26)
    }
    else
        return null;

    // any common lead-outs
    if (sorsa)
        return src +"\n"+ bsrc;
    else
        return g_template;
}


String mpExportBitmapData_CPC(int xwid, int yy)
{
    int x, y, ad, val1, val2, y2;
    int pix0b0, pix0b1, pix0b2, pix0b3;
    int pix1b0, pix1b1, pix1b2, pix1b3;
    String src = ";bitmap\n";

    for (y2 = 0; y2 < 8; y2++)
    {
        for (y = 0; y < 25; y++)
        {
            src += "  .byte ";
            for (x = 0; x < int(xwid / 2); x++) {
                ad = 1024 + (y * 8) * X + (y2 * X) + x * 4;

                val1 = int(g_map[ad]);
                pix0b0 = 0;
                pix0b1 = 0;
                pix0b2 = 0;
                pix0b3 = 0;
                if ((val1 & 1) != 0) pix0b0 = 1;
                if ((val1 & 2) != 0) pix0b1 = 1;
                if ((val1 & 4) != 0) pix0b2 = 1;
                if ((val1 & 8) != 0) pix0b3 = 1;

                val1 = int(g_map[ad + 2]);

                pix1b0 = 0;
                pix1b1 = 0;
                pix1b2 = 0;
                pix1b3 = 0;
                if ((val1 & 1) != 0) pix1b0 = 1;
                if ((val1 & 2) != 0) pix1b1 = 1;
                if ((val1 & 4) != 0) pix1b2 = 1;
                if ((val1 & 8) != 0) pix1b3 = 1;

                val2 = pix1b3 + pix0b3 * 2 + pix1b1 * 4 + pix0b1 * 8 + pix1b2 * 16 + pix0b2 * 32 + pix1b0 * 64 + pix0b0 * 128;

                src += str(int(val2));
                mpWriteByte(val2);

                if (x < int(xwid / 2) - 1) {
                    src += ",";
                }
            }
            src += "\n";
        }
        src += "  .byte ";

        for (int j = 0; j <= 47; j++)
        {
            mpWriteByte(0);
            src += str(int(0));
            if (j < 47) {
                src += ",";
            }
        }
        src += "\n";
    }
    src += "\n";
    return src;
}


String mpExportBitmapData(int xx, int yy)
{
    String src = "";
    //String src = "unsigned char img[]={";

    int linep = 0,
        xwid  = xx * 8,
        ywid = yy * 8;

    for (int y = 0; y < yy; y++)
    for (int x = 0; x < xx; x++)
    {
        // src += "  .byte ";
        src += "\t.db ";
        for (int y2 = 0; y2 < 8; y2++)
        {
            int ad = 1024 + y * (xwid * 8) + (y2 * xwid) + x * 8;
            int value =
                g_map[ad + 0] * 128 +
                g_map[ad + 1] * 64 +
                g_map[ad + 2] * 32 +
                g_map[ad + 3] * 16 +
                g_map[ad + 4] * 8 +
                g_map[ad + 5] * 4 +
                g_map[ad + 6] * 2 +
                g_map[ad + 7] * 1;

            src += str(int(value));
            mpWriteByte(int(value));

            if (y2 <= 6) {
                src += ",";
            }
        }
        src += "\n";
        if (++linep == xx)
        {
            linep = 0;
            src += "\n";
        }
    }
    src += "\n";

    return src;
}


int convertluminance(int l, int f)
{
    int res = 0;
    if (f == 0) return 0;
    if (l == 0) res = 0 + f;
    if (l == 1) res = 15 + f;
    if (l == 2) res = 30 + f;
    if (l == 3) res = 45 + f;
    if (l == 4) res = 60 + f;
    if (l == 5) res = 75 + f;
    if (l == 6) res = 90 + f;
    if (l == 7) res = 105 + f;
    return res;
}


int getplusluminance(int c)
{
    int res = 0;
    if (c == 0) res = 0;
    if (c >= 1 && c <= 15) res = 0;
    if (c >= 16 && c <= 30) res = 1;
    if (c >= 31 && c <= 45) res = 2;
    if (c >= 46 && c <= 60) res = 3;
    if (c >= 61 && c <= 75) res = 4;
    if (c >= 76 && c <= 90) res = 5;
    if (c >= 91 && c <= 105) res = 6;
    if (c >= 106 && c <= 120) res = 7;
    return res;
}


int getpluscolor(int c)
{
    int res = 0;
    if (c == 0) res = 0;
    if (c >= 1 && c <= 15) res = c;
    if (c >= 16 && c <= 30) res = c - 15;
    if (c >= 31 && c <= 45) res = c - 30;
    if (c >= 46 && c <= 60) res = c - 45;
    if (c >= 61 && c <= 75) res = c - 60;
    if (c >= 76 && c <= 90) res = c - 75;
    if (c >= 91 && c <= 105) res = c - 90;
    if (c >= 106 && c <= 120) res = c - 105;
    return res;
}


String mpExportColorData(int xx, int yy, int source, int param)
{
    int valu, valu2, kalu, muista, ad, linep, xwid, ywid, xoor, yline, myrpsi;
    String src = "";

    xwid = xx * 8;
    ywid = yy * 8;

    myrpsi = 0;
    xoor = xx;

    if (param == 0 || param == 4 || param == 5) {
        xoor = xx * 8;
    }
    if (machine == MSX) {
        myrpsi = 7;
    }
    if (param < 2) {
        src += "colora:\n";
    }
    if (param == 2) {
        src += "colorb:\n";
    }
    if (param < 2) {
        src += "  .byte " + int(g_map[0]) + "," + int(g_map[1]) +"\n";
    }
    if (param == 3) {
        //   src += "color:\n";
        //   src += "  .byte ";
        //  src += g_map[0]+" \n";
        xoor = xx * 8;
    }
    if (param == 4) {
        src += "_border:\n";
        src += "  .byte ";
        kalu = getpluscolor(int(g_map[0]));
        valu2 = getplusluminance(int(g_map[0]));
        valu = valu2 * 16 + kalu;
        src += valu + " \n";
        src += "_color:\n";
    }
    if (param == 5) {
        src += "_lumi:\n";
    }

    for (int y = 0; y < yy; y++)
    {
        //src += "  .byte ";
        src += "\t.db ";
        for (int x = 0; x < xx; x++)
        for (yline = 0; yline <= myrpsi; yline++)
        {
            ad = source + x + y * xoor + yline * xx;

            switch (param)
            {
                case 0:
                    valu = int(g_map[ad]);
                    valu2 = int(g_map[ad + MX * MY * 8]);
                    break;

                case 1:
                    valu2 = int(g_map[ad]);
                    valu = int(g_map[ad + 1000]);
                    break;

                case 2:
                    valu2 = int(g_map[ad]);
                    valu = 0;
                    break;

                case 3:
                    valu = int(g_map[ad]);
                    valu2 = int(g_map[ad + MX * MY * 8]);
                    break;

                case 4:
                    //plus4 colortable
                    valu = getpluscolor(int(g_map[ad]));
                    valu2 = getpluscolor(int(g_map[ad + MX * MY * 8]));
                    break;

                case 5:
                    //plus4 lumitable
                    valu = getplusluminance(int(g_map[ad + MX * MY * 8]));
                    valu2 = getplusluminance(int(g_map[ad]));
                    break;

                case 6:
                    //plus4 multic1
                    valu2 = getpluscolor(int(g_map[ad]));
                    valu = getpluscolor(int(g_map[ad + 1000]));
                    break;

                case 7:
                    //plus4 multic2
                    valu = getplusluminance(int(g_map[ad]));
                    valu2 = getplusluminance(int(g_map[ad + 1000]));
                    break;

                default:
                    return null;
            }

            src += str(valu * 16 + valu2);
            mpWriteByte(valu * 16 + valu2);
            if (x < (xx - 1) || yline < myrpsi)
            {
                src += ",";
            }
        }
        src += "\n";
    }

    return src +"\n";
}


boolean mpImportFromImage(PImage image)
{
    if (image == null)
        return false;

    if (image.width <= 16 || image.height <= 16)
        return false;

    int balx, baly, xx, yy, x2, y2, rr, gg, bb, avg, molox, i, j, target;
    int cx, cy;
    int aas, bbs, swap, idefix, avx, avy;
    int[] pixut = new int[260];
    int[] idx = new int[260];
    int[] histog = new int[8192];
    float ww, hh, fld, compa;
    color c;
    int xcolors, limitter, vertti, erkki;
    int rh, gh, bh;

    xcolors = g_maxcolors;
    vertti = 8;
    erkki = 1;
    limitter = 2;
    if (g_britemode == 1) {
        xcolors = 8;
    }
    if (g_attrimode == 0) {
        vertti = 1;
        erkki = 8;
    }
    if (g_multic == 1) {
        limitter = 4;
    } //because zero color can be anywhere?
    if (g_multic == 2) {
        limitter = 16;
    }
    molox = 1;
    command(int('O')); //special clear screen
    if (g_multic == 1 || g_hzoomer == 2) {
        molox = 2;
    }

    balx = int(image.width / X) * molox;
    baly = int(image.height / Y);
    if (balx < 1) {
        balx = 1;
    }
    if (baly < 1) {
        baly = 1;
    }

    if (g_palsteps > 0)
    {
        for (i = 0; i < g_maxcolors; i++) {
            makecolor(i, 0, 0, 0);
        }

        int maxhis, palls, psteps;
        psteps = int(g_palsteps - 1);
        maxhis = 0;
        palls = int(255 / psteps);

        for (cy = 0; cy < MY * erkki; cy++)
        for (cx = 0; cx < MX; cx++)
        for (yy = cy * vertti; yy <= cy * vertti + vertti - 1; yy++)
        for (xx = cx * 8; xx <= cx * 8 + 7; xx = xx + molox)
        {
            x2 = int(image.width / X) * xx;
            y2 = int(image.height / Y) * yy;
            rr = 0;
            gg = 0;
            bb = 0;
            avg = 0;

            for (avy = 0; avy < baly; avy++) {
                for (avx = 0; avx < balx; avx++) {
                    c = image.get(x2 + avx, y2 + avy);
                    rr = rr + int(red(c));
                    gg = gg + int(green(c));
                    bb = bb + int(blue(c));
                    avg++;
                }
            }

            rh = rr / (avg);
            gh = gg / (avg);
            bh = bb / (avg);

            rh = int(rh) / palls;
            gh = int(gh) / palls;
            bh = int(bh) / palls;
            histog[int(rh * (g_palsteps * g_palsteps) + gh * (g_palsteps) + bh)]++;

            if (histog[int(rh * (g_palsteps * g_palsteps) + gh * (g_palsteps) + bh)] > maxhis) {
                maxhis = histog[int(rh * (g_palsteps * g_palsteps) + gh * (g_palsteps) + bh)];
            }
        }

        int step = 0;
        for (j = maxhis; j > 0; j--)
        for (i = 0; i <= 4096; i++)
        {
            if (histog[i] == j)
            {
                rh = i / int(g_palsteps * g_palsteps);
                gh = i - int(rh * (g_palsteps * g_palsteps));
                gh = gh / int(g_palsteps);
                bh = i - int(rh * (g_palsteps * g_palsteps));
                bh = bh - int(gh * g_palsteps);
                rh = rh * int(palls);
                gh = gh * int(palls);
                bh = bh * int(palls);
                if (step < g_maxcolors) {
                    makecolor(step, rh, gh, bh);
                    step++;
                }
            }
        }
    }

    for (cy = 0; cy < MY * erkki; cy++)
    for (cx = 0; cx < MX; cx++) {
        for (i = 0; i < xcolors; i++) {
            pixut[i] = 0;
            idx[i] = i;
        }
        for (yy = cy * vertti; yy <= cy * vertti + vertti - 1; yy++) {
            for (xx = cx * 8; xx <= cx * 8 + 7; xx = xx + molox) {
                x2 = int(image.width / X) * xx;
                y2 = int(image.height / Y) * yy;
                rr = 0;
                gg = 0;
                bb = 0;
                avg = 0;
                for (avy = 0; avy < baly; avy++) {
                    for (avx = 0; avx < balx; avx++) {
                        c = image.get(x2 + avx, y2 + avy);
                        rr = rr + int(red(c));
                        gg = gg + int(green(c));
                        bb = bb + int(blue(c));
                        avg++;
                    }
                }
                rr = rr / (avg);
                gg = gg / (avg);
                bb = bb / (avg);
                g_farge = 0;
                target = -1;
                compa = 9999;
                for (i = 0; i < xcolors; i++) {
                    fld = dist(rr, gg, bb, g_r[i], g_g[i], g_b[i]);
                    if (fld < compa) {
                        compa = fld;
                        target = i;
                    }
                }

                g_farge = target;
                pixut[target]++; //histogramming
            }
        }

        for (aas = 0; aas < xcolors; aas++)
        for (bbs = 0; bbs <= aas; bbs++)
        {
            if (pixut[aas] > pixut[bbs])
            {
                swap = pixut[aas];
                pixut[aas] = pixut[bbs];
                pixut[bbs] = swap;
                swap = idx[aas];
                idx[aas] = idx[bbs];
                idx[bbs] = swap;
            }
        }

        for (idefix = 0; idefix < limitter; idefix++)
        {
            i = idx[idefix];
            for (yy = cy * vertti; yy <= cy * vertti + vertti - 1; yy++)
            {
                for (xx = cx * 8; xx <= cx * 8 + 7; xx = xx + molox)
                {

                    x2 = int(image.width / X) * xx;
                    y2 = int(image.height / Y) * yy;

                    rr = 0;
                    gg = 0;
                    bb = 0;
                    avg = 0;
                    for (avy = 0; avy < baly; avy++) {
                        for (avx = 0; avx < balx; avx++) {
                            c = image.get(x2 + avx, y2 + avy);
                            rr = rr + int(red(c));
                            gg = gg + int(green(c));
                            bb = bb + int(blue(c));
                            avg++;
                        }
                    }
                    rr = rr / (avg);
                    gg = gg / (avg);
                    bb = bb / (avg);
                    g_farge = 0;
                    target = -1;
                    compa = 9999;
                    for (j = 0; j < limitter; j++) {
                        fld = dist(rr, gg, bb, g_r[idx[j]], g_g[idx[j]], g_b[idx[j]]);
                        if (fld < compa) {
                            compa = fld;
                            target = idx[j];
                        }
                    }
                    if (i == target) {

                        g_farge = target;
                        makepoint(xx, yy);
                    }
                }
            }

            if (idefix == 0) {
                for (yy = cy * vertti; yy <= cy * vertti + vertti - 1; yy++) {
                    for (xx = cx * 8; xx <= cx * 8 + 7; xx = xx + molox) {
                        g_farge = idx[0];
                        makepoint(xx, yy);
                    }
                }
            }
        }
    }
}


void mpRenderToImageAt(PImage output, int xoffs, int yoffs)
{
    if (output == null)
        return;

    for (int yy = 0; yy < output.width; yy++)
    for (int xx = 0; xx < output.width; xx++)
    {
        color c = color(g_r[259], g_g[259], g_b[259]);
        output.set(xx, yy, c);
    }

    for (int yy = 0; yy < Y; yy++)
    for (int xx = 0; xx < X; xx++)
    {
        int f;
        if (g_multic == 1 || g_hzoomer == 2)
            f = getmultic(chop2(xx), yy, 0);
        else
            f = getabsa(xx, yy, 0);

        if (machine == MSX && f == 0)
            f = g_map[1];

        color c = color(g_r[f], g_g[f], g_b[f]);

        for (int vertti = 0; vertti <= g_omag; vertti++)
        for (int mortti = 0; mortti <= g_omag; mortti++)
        {
            output.set(
                xx * g_omag + xoffs + mortti,
                yy * g_omag + yoffs + vertti,
                c);
        }
    }
}


PImage mpRenderImage(boolean border)
{
    PImage output;

    if (border)
    {
        pimage = createImage(
            X * g_omag + g_bordh * g_omag,
            Y * g_omag + g_bordv * g_omag,
            RGB);

        mpRenderToImageAt(output, int((g_bordh * g_omag) / 2), int((g_bordv * g_omag) / 2));
    }
    else
    {
        output = createImage(X * g_omag, Y * g_omag, RGB);
        mpRenderToImageAt(output, 0, 0);
    }

    return output;
}


void make_c64_palette() {
    // Pepto's murky C64 palette: http://www.pepto.de/projects/colorvic
    int rgb[] = {
        0xff000000,
        0xffFFFFFF,
        0xff68372B,
        0xff70A4B2,
        0xff6F3D86,
        0xff588D43,
        0xff352879,
        0xffB8C76F,
        0xff6F4F25,
        0xff433900,
        0xff9A6759,
        0xff444444,
        0xff6C6C6C,
        0xff9AD284,
        0xff6C5EB5,
        0xff959595
    };
    for (int i = 0; i < g_maxcolors; i++) {
        rgb[i] = rgb[i] & 0xffffff;
        g_grids[i] = rgb[i] + 0xff282828;
        makecolor(i, rgb[i] >> 16, (rgb[i] & 0xff00FF00) >> 8, rgb[i] & 0xff0000FF);
    }
    g_grids[1] = 0xffd0d0d0;
    g_gridmode = NEW;
    g_map[13] = byte(C64);
}

void make_plus4_palette() {
    int rgb[] = {
        0xff000000,
        0xff2C2C2C,
        0xff621307,
        0xff00424C,
        0xff510378,
        0xff004E00,
        0xff27188E,
        0xff303E00,
        0xff582100,
        0xff463000,
        0xff244400,
        0xff630448,
        0xff004E0C,
        0xff0E2784,
        0xff33118E,
        0xff184800,
        0xff3B3B3B,
        0xff702419,
        0xff00505A,
        0xff601685,
        0xff125D00,
        0xff36289B,
        0xff3F4C00,
        0xff663100,
        0xff553F00,
        0xff345200,
        0xff711656,
        0xff005C1D,
        0xff1F3691,
        0xff42229B,
        0xff285700,
        0xff424242,
        0xff772C21,
        0xff055861,
        0xff661E8C,
        0xff1B6400,
        0xff3E30A2,
        0xff475400,
        0xff6D3900,
        0xff5C4700,
        0xff3B5900,
        0xff771F5D,
        0xff046325,
        0xff273E98,
        0xff492AA1,
        0xff305E00,
        0xff515151,
        0xff843B31,
        0xff17656F,
        0xff742E99,
        0xff2B7100,
        0xff4C3FAF,
        0xff556200,
        0xff7A4709,
        0xff6A5500,
        0xff4A6700,
        0xff852F6B,
        0xff177135,
        0xff364CA5,
        0xff5739AE,
        0xff3F6B00,
        0xff7A7A7A,
        0xffAC665C,
        0xff468E97,
        0xff9C5AC0,
        0xff57992E,
        0xff766AD5,
        0xff7E8A13,
        0xffA2713A,
        0xff927E20,
        0xff748F14,
        0xffAC5A93,
        0xff459960,
        0xff6276CB,
        0xff8064D4,
        0xff6A9419,
        0xff959595,
        0xffC58178,
        0xff62A8B1,
        0xffB675D9,
        0xff73B34C,
        0xff9185ED,
        0xff99A433,
        0xffBB8C57,
        0xffAC993E,
        0xff8FAA34,
        0xffC676AD,
        0xff62B37B,
        0xff7D91E4,
        0xff9B80ED,
        0xff85AE38,
        0xffAFAFAF,
        0xffDE9B93,
        0xff7DC2CA,
        0xffCF90F2,
        0xff8DCD68,
        0xffAB9FFF,
        0xffB3BE51,
        0xffD5A673,
        0xffC6B35B,
        0xffA9C351,
        0xffDF91C7,
        0xff7DCC96,
        0xff97ABFD,
        0xffB59AFF,
        0xff9FC755,
        0xffE1E1E1,
        0xffFFCFC6,
        0xffB2F4FC,
        0xffFFC4FF,
        0xffC1FE9D,
        0xffDDD2FF,
        0xffE5F088,
        0xffFFD9A8,
        0xffF7E591,
        0xffDBF588,
        0xffFFC4F9,
        0xffB1FEC9,
        0xffCBDDFF,
        0xffE7CDFF,
        0xffD2F98C
    };
    for (int i = 0; i < g_maxcolors; i++) {
        rgb[i] = rgb[i] & 0xffffff;
        makecolor(i, rgb[i] >> 16, (rgb[i] & 0xff00FF00) >> 8, rgb[i] & 0xff0000FF);
    }
}

void make_msx_palette() {
    int rgb[] = {
        0xff000000,
        0xff000000,
        0xff3EB849,
        0xff74D07D,
        0xff5955E0,
        0xff8076F1,
        0xffB95E51,
        0xff65DBEF,
        0xffDB6559,
        0xffFF897D,
        0xffCCC35E,
        0xffDED087,
        0xff3AA241,
        0xffB766B5,
        0xffCCCCCC,
        0xffFFFFFF
    };

    for (int i = 0; i < g_maxcolors; i++) {
        rgb[i] = rgb[i] & 0xffffff;
        g_grids[i] = rgb[i] + 0xff1f1f1f;
        makecolor(i, (rgb[i] >> 16), (rgb[i] & 0xff00FF00) >> 8, rgb[i] & 0xff0000FF);
    }
    g_grids[5] = 0xff9f95Ff;
    g_grids[7] = 0xff84faEF;
    g_grids[9] = 0xffffa99d;
    g_grids[15] = 0xffd8d8d8;
    g_gridmode = NEW;
}

void make_spectrum_palette() {
    int rgb[] = {
        0xff000000,
        0xff0000C0,
        0xffC00000,
        0xffC000C0,
        0xff00C000,
        0xff00C0C0,
        0xffC0C000,
        0xffC0C0C0,
        0xff000000,
        0xff0000FF,
        0xffFF0000,
        0xffFF00FF,
        0xff00FF00,
        0xff00FFFF,
        0xffFFFF00,
        0xffFFFFFF
    };

    g_grids[9] = 0xff0000d8;
    g_grids[10] = 0xffd80000;
    g_grids[11] = 0xffd800d8;
    g_grids[12] = 0xff00d800;
    g_grids[13] = 0xff00d8d8;
    g_grids[14] = 0xffd8d800;
    g_grids[15] = 0xffd8d8d8;
    for (int i = 0; i < g_maxcolors; i++) {
        rgb[i] = rgb[i] & 0xffffff;
        if (i <= 8) {
            g_grids[i] = rgb[i] + 0xff282828;
        }
        makecolor(i, (rgb[i] >> 16), (rgb[i] & 0xff00FF00) >> 8, rgb[i] & 0xff0000FF);
    }
    g_gridmode = NEW;
}


void mpSetupMachine(int m)
{
    machine = m;
    g_exportext = "none";
    g_map[3] = byte(machine);
    g_map[13] = byte(machine);
    g_palsteps = 0;
    g_farge = 1;
    g_backg = 0;
    g_britemode = 0;
    g_charlimit = 0;
    g_hzoomer = 1;
    g_backmode = 0;
    g_formatname = "";
    g_formatext = "";
    g_maxcolors = 16;
    X = 320;
    Y = 200;

    if (machine == C64) { //c64 hires
        g_name = "c64";
        g_exportext = "prg";
        g_exportname = "PRG file";
        g_formatname = "Art Studio";
        g_formatext = "art";

        g_attrimode = 1;
        g_map[1] = byte(255);
        g_map[0] = 6;
        make_c64_palette();
    }
    else
    if (machine == CPC) { //Amstrad CPC mode 0
        g_name = "cpc";
        g_exportext = "bin";
        g_exportname = "BIN file"
        g_formatname = "";
        g_formatext = "";

        g_hzoomer = 2;
        g_palsteps = 3;
        g_multic = 2;
        g_attrimode = 0;
        g_map[1] = byte(255);
        g_map[0] = 1;

        makecolor(0, 0, 0, 0);
        makecolor(1, 0x0, 0x0, 0x80);
        makecolor(2, 0x00, 0x00, 0xFF);
        makecolor(3, 0x80, 0x00, 0x00);
        makecolor(4, 0x80, 0x00, 0x80);
        makecolor(5, 0x80, 0x00, 0xFF);
        makecolor(6, 0xFF, 0x00, 0x00);
        makecolor(7, 0xFF, 0x00, 0x80);
        makecolor(8, 0xFF, 0x00, 0xFF);
        makecolor(9, 0x00, 0x80, 0x00);
        makecolor(10, 0x00, 0x80, 0x80);
        makecolor(11, 0x00, 0x80, 0xFF);
        makecolor(12, 0x80, 0x80, 0x00);
        makecolor(13, 0x80, 0x80, 0x80);
        makecolor(14, 0x80, 0x80, 0xFF);
        makecolor(15, 0xFF, 0xFF, 0xFF);
    }
    else
    if (machine == MSX) { // MSX
        g_name = "msx";
        g_exportext = "com";
        g_exportname = "COM file";
        g_formatname = "Screen 2";
        g_formatext = "sc2";

        X = 256;
        Y = 192;
        g_attrimode = 0;
        g_backmode = 1;
        g_farge = 15;
        g_backg = 0;

        //TI99 variant
        /*
        makecolor(0,0,0,0);
        makecolor(1,0,0,0);

        makecolor(2,0x21,0xc8,0x42); //21c842 medgreen
        makecolor(3,0x5e,0xdc,0x78);//5edc78 light green
        makecolor(4,0x54,0x55,0xed);//5455ed dark blue
        makecolor(5,0x7d,0x76,0xFc);//7d76fc light blue

        makecolor(6,0xd4,0x52,0x4d); //d4524d dark red
        makecolor(7,0x42,0xeb,0xf5); //42ebf5 cyan
        makecolor(8,0xfc,0x55,0x54); //fc5554 medium red
        makecolor(9,0xff,0x79,0x78); //ff7978 light red
        makecolor(10,0xd4,0xc1,0x54);// d4c154 dark yellow
        makecolor(11,0xe6,0xce,0x80);// e6ce80 light yellow
        makecolor(12,0x21,0xb0,0x3b);// 21b03b dark green
        makecolor(13,0xc9,0x5b,0xba);// c95bba magenta
        makecolor(14,0xCc,0xcc,0xCc);// gray
        makecolor(15,0xFF,0xFF,0xFF);
        */
        make_msx_palette();
    }
    else
    if (machine == SPECTRUM) { // ZX Spectrum
        g_name = "spec";
        g_exportext = "tap";
        g_exportname = "TAP file";
        g_formatname = "Screen$";
        g_formatext = "scr";

        X = 256;
        Y = 192;
        g_farge = 7;
        g_backg = 0;
        g_attrimode = 1;
        g_britemode = 1;
        g_map[0] = 1;
        g_map[1] = byte(255);
        make_spectrum_palette();
    }
    else
    if (machine == TIMEX) { // timex sinclair
        g_name = "tmx";

        X = 256;
        Y = 192;
        g_farge = 7;
        g_backg = 0;
        g_attrimode = 0;
        g_britemode = 1;
        g_map[1] = byte(255);
        make_spectrum_palette();
    }
    else
    if (machine == JR200) { // Panasonic JR200
        g_name = "jr200";

        X = 256;
        Y = 192;
        g_maxcolors = 8;
        g_farge = 7;
        g_backg = 0;
        g_attrimode = 1;
        g_map[1] = byte(255);
        make_spectrum_palette(); //cheating
    }
    else
    if (machine == PLUS4M || machine == PLUS4) { // Commodore plus/4
        g_name = "plus4m";
        g_exportext = "prg";
        g_exportname = "PRG file";
        g_formatname = "M.Botticelli";
        g_formatext = "prg";

        g_backmode = 1;
        g_multic = 1;
        g_attrimode = 1;
        g_maxcolors = 121;
        g_charlimit = 2;
        g_map[0] = 6;
        g_map[1] = 0;
        g_map[2] = 61;
        g_farge = 61;

        if (machine == PLUS4) { // plus/4 hires
            g_name = "plus4";
            g_formatname = "Botticelli";
            g_formatext = "prg";
            g_multic = 0;
            g_backmode = 0;
            g_charlimit = 0;
            g_attrimode = 1;
            g_map[1] = byte(255);
        }
        make_plus4_palette();
    }
    else
    if (machine == C64M) { //c64 multicolor
        g_name = "c64m";
        g_exportext = "prg";
        g_exportname = "PRG file";
        g_formatname = "A. A. Studio";
        g_formatext = "ocp";

        g_backmode = 1;
        g_charlimit = 3;
        g_multic = 1;
        g_attrimode = 1;
        g_map[1] = byte(0);
        g_map[0] = 6;
        make_c64_palette();
    }
    else
    if (machine == AMIGA) { //generic 16bit
        g_name = "test";
        g_exportext = "";
        g_exportname = "";
        g_formatname = "";
        g_formatext = "";

        g_backmode = 1;
        g_maxcolors = 32;
        g_palsteps = 16;
        g_multic = 2;
        g_attrimode = 2;
        g_map[1] = byte(0);
        for (int z = 0; z < g_maxcolors; z++) {
            if (z < 16) {
                makecolor(z, z * 17, z * 17, z * 17);
            } else {
                makecolor(z, (z - 16) * 17, 0, 0);
            }
        }
    }
    else
    if (machine == C64FLI) { //c64 hires FLI = AFLI
        g_name = "afli";
        g_exportext = "prg";
        g_exportname = "PRG file";
        g_formatname = "";
        g_formatext = "";

        g_attrimode = 0;
        g_map[1] = byte(255);
        g_map[0] = 6;
        make_c64_palette();
    }
    else
    if (machine == C64FLIM) { //C64 FLI multicolor
        g_name = "fli";
        g_exportext = "";
        g_exportname = "PRG file";
        g_formatname = "";
        g_formatext = "";

        g_hzoomer = 2;
        g_maxcolors = 16;
        g_multic = 2;
        g_attrimode = 0;
        g_map[1] = byte(255);
        g_map[0] = 6;
        make_c64_palette();
    }
    else
    if (machine == FAKEX) { // Fake 8-bit computer
        g_name = "fake";
        g_exportext = "";
        g_exportname = "";
        g_formatname = "";
        g_formatext = "";

        X = 320;
        Y = 200;
        g_multic = 2;
        g_attrimode = 2; //g_palsteps=4;
        g_farge = 15;
        g_backg = 0;
        make_c64_palette();
    }
    else
    if (machine == PICO8) { // Pico-8 fantasy console
        g_name = "pico8";
        g_exportext = "";
        g_exportname = "";
        g_formatname = "";
        g_formatext = "";

        X = 128;
        Y = 128;
        g_farge = 15;
        g_backg = 0;
        g_multic = 2;
        g_attrimode = 2;
        makecolor(0, 0, 0, 0);
        makecolor(1, 32, 51, 123);
        makecolor(2, 126, 37, 83);
        makecolor(3, 0, 144, 61);
        makecolor(4, 171, 82, 54);
        makecolor(5, 52, 54, 53);
        makecolor(6, 194, 195, 199);
        makecolor(7, 255, 241, 232);
        makecolor(8, 255, 0, 77);
        makecolor(9, 255, 155, 0);
        makecolor(10, 255, 231, 39);
        makecolor(11, 0, 226, 50);
        makecolor(12, 41, 173, 255);
        makecolor(13, 132, 112, 169);
        makecolor(14, 255, 119, 168);
        makecolor(15, 255, 214, 197);
    }
    else
    if (machine == UNIA) { // Unia digital palette
        g_name = "unia";
        g_exportext = "";
        g_exportname = "";
        g_formatname = "";
        g_formatext = "";

        X = 256;
        Y = 192;
        g_farge = 15;
        g_backg = 0;
        g_multic = 2;
        g_attrimode = 2;
        makecolor(0, 0, 0, 0);
        makecolor(1, 0xff, 0xff, 0xff);
        makecolor(2, 0xff, 0xfd, 0x38);
        makecolor(3, 0xff, 0xc5, 0x00);
        makecolor(4, 0xff, 0x00, 0x00);
        makecolor(5, 0xff, 0x3c, 0xb4);
        makecolor(6, 0xa0, 0x23, 0xbc);
        makecolor(7, 0x1b, 0xa1, 0xfc);
        makecolor(8, 0xe1, 0xe1, 0xe1);
        makecolor(9, 0xb9, 0x63, 0x00);
        makecolor(10, 0xff, 0xaa, 0xbe);
        makecolor(11, 0xd2, 0x9b, 0xd7);
        makecolor(12, 0xad, 0xad, 0xad);
        makecolor(13, 0x00, 0xb7, 0xb7);
        makecolor(14, 0x23, 0xaf, 0x32);
        makecolor(15, 0x29, 0xf7, 0xa7);
    }
}