view exporters.pde @ 88:03823fa2cb01

Refactor export_image() and export_image_sans_border() to use common code, and also rename them to mpRenderImageWithBorder() and mpRenderImageWithoutBorder().
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 06 Jul 2018 00:23:23 +0300
parents 8dd5146c881f
children dffafe05d520
line wrap: on
line source

// machine definitions
// source writer and other export/import functions
// the machine_export() makes use of bitmapexport() and colorexport() below
// 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 mpSetByte(int moffs, int toffs)
{
    g_map[moffs    ] = byte((g_template[toffs] & 128) >> 7);
    g_map[moffs + 1] = byte((g_template[toffs] & 64) >> 6);
    g_map[moffs + 2] = byte((g_template[toffs] & 32) >> 5);
    g_map[moffs + 3] = byte((g_template[toffs] & 16) >> 4);
    g_map[moffs + 4] = byte((g_template[toffs] & 8) >> 3);
    g_map[moffs + 5] = byte((g_template[toffs] & 4) >> 2);
    g_map[moffs + 6] = byte((g_template[toffs] & 2) >> 1);
    g_map[moffs + 7] = byte( g_template[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);
}


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

    g_template = fdata;
    head = 0;

    if (machine == SPECTRUM) //SCR=SCREEN$
    {
        // 32*24*8 bytes of bitmap
        // 32*24 bytes of attributes
        if (g_template.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;
            mpSetByte(ad, head);
            head++;
        }

        for (y = 0; y < 24; y++)
        for (x = 0; x < 32; x++)
        {
            ad = 65536 + x + y * (32 * 8);
            valu = g_template[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 (g_template.length < 9006) {
            return false;
        }
        if (g_template.length >= 0x232a) {
            g_map[0] = byte(g_template[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;
            mpSetByte(ad, head);
            p1 = g_template[0x1f42 + x + y * 40] & 0x0f;
            p2 = g_template[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 (g_template.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;
            mpSetByte(ad, head);

            p1 = g_template[1026 + x + y * 40] & 0x0f;
            p2 = g_template[1026 + x + y * 40] & 0xf0;
            p2 = p2 >> 4;
            l1 = g_template[2 + x + y * 40] & 0x0f;
            l2 = g_template[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 (g_template.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;
            mpSetByte(ad, head);

            p1 = g_template[1026 + x + y * 40] & 0x0f;
            p2 = g_template[1026 + x + y * 40] & 0xf0;
            p2 = p2 >> 4;
            l1 = g_template[2 + x + y * 40] & 0x0f;
            l2 = g_template[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(g_template[1025]) & 0xf0;
        l1 = int(g_template[1025]) & 0x0f;
        p1 = p1 >> 4;
        g_map[1] = byte(convertluminance(l1, p1));
        p1 = int(g_template[1024]) & 0xf0;
        l1 = int(g_template[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 (g_template.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;
            mpSetByte(ad, head);

            p1 = g_template[0x1f42 + x + y * 40] & 0x0f;
            p2 = (g_template[0x1f42 + x + y * 40] >> 4) & 0x0f;
            p3 = g_template[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(g_template[0x232a] & 0x0f); //bord
        g_map[1] = byte(g_template[0x232b] & 0x0f); //baku
    }
    else
    if (machine == MSX) { // sc2
        // 7=bitmap 32*24*8
        // 7+(32*24*8)=colormap 32*24
        if (g_template.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;
            mpSetByte(ad, head);
            p1 = g_template[(8199) + x * 8 + ((y * 8 * 32) + y2)] & 0x0f;
            p2 = g_template[(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;
}


void format_export(String fname)
{
    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);
        export_program(fname);
    }
    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);
        export_program(fname);
    }
    else
    if (machine == C64) {
        mpLoadTemplate("hires.art");
        mpSetDataOffs(2);
        mpExportBitmapData(40, 25);
        mpSetDataOffs(0x1f42);
        mpExportColorData(40, 25, 65536, 0);
        mpSetDataOffs(0x232a);
        mpWriteByte(int(g_map[0]));
        export_program(fname);
    }
    else
    if (machine == C64M) {
        if (fname.indexOf(".kla") >= 0)
        {
            // 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(int(g_map[1] & 0x0f));
        }
        else
        {
            // 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(int(g_map[0]));
            mpSetDataOffs(0x232b);
            mpWriteByte(int(g_map[1]));
        }
        export_program(fname);
    }
    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
        export_program(fname);
    }
    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(int(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(int(valu + valu2 * 8));
        }
        export_program(fname);
    }
}


void machine_export(String fname, int sorsa) {
    int yy, xx, x, y2, y, checksum;
    int xp, yp;
    int valu, valu2;
    int val1, val2, val3;
    int ad, by;
    int bri, skyp;
    g_sorsaa = sorsa; //aargh another global

    if (sorsa == 1) {
        exwriter = createWriter(fname);
    }

    // any common text headers
    by = 0;
    skyp = 0;
    outputter(";machine=" + str(machine) + " (" + g_name + ")", true);

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

        mpLoadTemplate("c64show.prg");
        mpSetDataOffs(0X0227);
        mpExportBitmapData(40, 25);
        mpSetDataOffs(0X2167);
        mpWriteByte(g_map[0]); //=border
        mpSetDataOffs(0X2168);
        mpWriteByte(g_map[1]); //=background mutta ei tarvita
        mpSetDataOffs(0X2169);
        outputter("; The following two first values are border and background", true);
        mpExportColorData(40, 25, 65536, 0);
        export_program(fname);

        //c64show.prg
        //offsets
        //0x0227->bitmappi (40x25 x 8 bytee)
        //0x2167:borderi väri
        //0x2169->värikartta (40x25 bytee, nyppelit foreg/backg)
    }

    if (machine == C64M) { //C64 MULTICOLOR

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

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

        // second color information
        mpSetDataOffs(0x2563);
        outputter("; The following goes to $D800 onwards", true);
        mpExportColorData(40, 25, 65536 + 2000, 2);
        export_program(fname);

        //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-)
    }

    if (machine == PLUS4M) { //PLUS4 MULTICOLOR
        mpLoadTemplate("showpfourm.prg");
        outputter("  .global _bitmap", true);
        outputter("  .global _color1", true);
        outputter("  .global _color2", true);
        outputter("  .global _border", true);
        outputter("  .global _back1", true);
        outputter("  .global _back2", true);
        outputter("_bitmap:", true);
        mpSetDataOffs(0x013e);
        mpExportBitmapData(40, 25);
        outputter("_border:", true);
        val1 = getpluscolor(int(g_map[0]));
        val2 = getplusluminance(int(g_map[0]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(0x207e);
        mpWriteByte(val3);
        outputter("  .byte " + val3, true);
        outputter("_back1:", true);
        val1 = getpluscolor(int(g_map[1]));
        val2 = getplusluminance(int(g_map[1]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(0x207f);
        mpWriteByte(val3);
        outputter("  .byte " + val3, true);
        outputter("_back2:", true);
        val1 = getpluscolor(int(g_map[2]));
        val2 = getplusluminance(int(g_map[2]));
        val3 = val2 * 16 + val1;
        mpSetDataOffs(0x2080);
        mpWriteByte(val3);
        outputter("  .byte " + val3, true);
        outputter("_color1:", true);
        mpSetDataOffs(0x2081);
        mpExportColorData(40, 25, 65536, 6);
        outputter("_color2:", true);
        mpSetDataOffs(0x2469);
        mpExportColorData(40, 25, 65536, 7);
        export_program(fname);
        //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)
    }

    if (machine == PLUS4) { // Plus 4 hires
        mpLoadTemplate("showpfour.prg");
        outputter("  .global _bitmap", true);
        outputter("  .global _color", true);
        outputter("  .global _lumi", true);
        outputter("  .global _border", true);
        outputter("_bitmap:", true);
        mpSetDataOffs(0x0137);
        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);
        mpExportColorData(40, 25, 65536, 4); //colors
        mpSetDataOffs(0x2460);
        mpExportColorData(40, 25, 65536, 5); //lumis
        export_program(fname);
        //plus4 hires
        //0x0137   bitmap (40 x 25 x 8)
        //0x2077   borderi
        //0x2078   colors (40 x 25)
        //0x2460   luminance (40 x 25)
    }

    if (machine == MSX) { // MSX
        mpLoadTemplate("msxshow.com");
        mpSetDataOffs(0x00f9);
        outputter(char(9) + ".globl _nimi1,_nimi2", true);
        outputter(char(9) + ".area _CODE", true);
        outputter("_nimi1:", true);
        mpExportBitmapData(32, 24);
        mpSetDataOffs(0x18f9);
        //mpWriteByte(g_map[1]); //backg
        //outputter("; The first following value is background", true);
        outputter("_nimi2:", true);
        mpExportColorData(32, 24, 65536, 3); //there's an exception for msx-style
        export_program(fname);
        //msx comm
        //0x00f9 bitmap (32x24 x 8 bytes)
        //0x18f9 background color
        //0x18fa colors (32*24 bytes)
    }

    if (machine == SPECTRUM) { // ZX Spectrum

        //would need some cleaning up

        //  outputter("  .area  _DATA",true);
        //  outputter("  .globl _taustakuva",true);
        //  outputter("",true);
        //  outputter("_taustakuva:",true);
        mpLoadTemplate("specshow.tap");
        int stad;

        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);
        outputter(".byte " + (str(g_map[0])) + " ;border", true);
        mpWriteByte(int(g_map[0]));
        checksum = checksum ^ int(g_map[0]);
        for (y = 0; y <= 2; y++)
        for (y2 = 0; y2 <= 7; y2++)
        for (yy = 0; yy <= 7; yy++)
        {
            outputter(".byte ", false);
            for (x = 0; x <= 31; x++)
            {
                yp = y * 64 + yy * 8 + y2;
                xp = x;
                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;
                outputter(str(int(valu)), false);
                by++;
                mpWriteByte(int(valu));
                checksum = checksum ^ int(valu);
                if (x <= 30) {
                    outputter(",", false);
                }
            }
            outputter("", true);
        }

        outputter("; attributes", true);
        for (y = 0; y <= 24; y++)
        {
            outputter(".byte ", false);
            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 = valu + 64;
                }
                outputter(str(valu + valu2 * 8), false);
                by++;
                mpWriteByte(int(valu + valu2 * 8));
                checksum = checksum ^ int(valu + valu2 * 8);
                if (x <= 30) {
                    outputter(",", false);
                }
            }
            outputter("", true);
        }
        //println("checksum:"+hex(checksum,2));
        mpSetDataOffs(0x1d3e);
        mpWriteByte(int(checksum));
        export_program(fname);
    }

    if (machine == CPC) {
        mpLoadTemplate("cpc-mode0.bin");

        mpSetDataOffs(69); //bitmap offset
        mpExportBitmapData_CPC(160, 200);
        mpSetDataOffs(16453);
        outputter(";palette", true);
        outputter(".byte ", false);
        //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);
            outputter(str(val1 * 9 + val2 * 3 + val3), false);
            if (i < g_maxcolors - 1) {
                outputter(",", false);
            }
        }
        outputter("", true);
        outputter(";border", true);
        outputter(".byte ", false);
        mpSetDataOffs(16469);
        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));
        mpWriteByte(val1 * 9 + val2 * 3 + val3);
        outputter(str(val1 * 9 + val2 * 3 + val3), false);
        //cpc
        //69    bitmap 16384 bytes
        //16453 palette 16 bytes (0..26)
        //16469 border color (0..26)
        export_program(fname);
    }

    // any common lead-outs

    if (sorsa == 1) {
        exwriter.flush();
        exwriter.close();
    }
}


void mpExportBitmapData_CPC(int xwid, int yy)
{
    int x, y, ad, val1, val2, y2;
    int pix0b0, pix0b1, pix0b2, pix0b3;
    int pix1b0, pix1b1, pix1b2, pix1b3;
    int pp;
    pp = 0;
    outputter(";bitmap", true);
    for (y2 = 0; y2 <= 7; y2++) {
        for (y = 0; y < 25; y++) {
            outputter("  .byte ", false);
            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;
                outputter(str(int(val2)), false);
                mpWriteByte(val2);
                pp++;
                if (x < int(xwid / 2) - 1) {
                    outputter(",", false);
                }
            }
            outputter("", true);
        }
        outputter("  .byte ", false);
        for (int j = 0; j <= 47; j++) {
            mpWriteByte(0);
            outputter(str(int(0)), false);
            pp++;
            if (j < 47) {
                outputter(",", false);
            }
        }
        outputter("", true);
    }
    outputter("", true);
}


void mpExportBitmapData(int xx, int yy)
{
    int xwid, ywid, x, y, y2, value, ad, linep;
    linep = 0;
    xwid = xx * 8;
    ywid = yy * 8;
    //outputter("unsigned char img[]={",false);

    for (y = 0; y < yy; y++) {
        for (x = 0; x < xx; x++) {
            //            outputter("  .byte ", false);
            outputter(char(9) + ".db ", false);
            for (y2 = 0; y2 <= 7; y2++) {
                ad = 1024 + y * (xwid * 8) + (y2 * xwid) + x * 8;
                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;
                outputter(str(int(value)), false);
                mpWriteByte(int(value));
                if (y2 <= 6) {
                    outputter(",", false);
                }
            }
            outputter("", true);
            linep++;
            if (linep == xx) {
                linep = 0;
                outputter("", true);
            }
        }
    }
    outputter("", true);
}


int convertlumi(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;
}

void mpExportColorData(int xx, int yy, int source, int param) {
    int x, y, y2, valu, valu2, kalu, muista, ad, linep, xwid, ywid, xoor, yline, myrpsi;
    xwid = xx * 8;
    ywid = yy * 8;
    valu = 0;
    valu2 = 0;
    myrpsi = 0;
    xoor = xx;
    if (param == 0 || param == 4 || param == 5) {
        xoor = xx * 8;
    }
    if (machine == MSX) {
        myrpsi = 7;
    }
    if (param < 2) {
        outputter("colora:", true);
    }
    if (param == 2) {
        outputter("colorb:", true);
    }
    if (param < 2) {
        outputter("  .byte " + int(g_map[0]) + "," + int(g_map[1]), true);
    }
    if (param == 3) {
        //   outputter("color:", true);
        //   outputter("  .byte ", false);
        //  outputter(g_map[0]+" ", true);
        xoor = xx * 8;
    }
    if (param == 4) {
        outputter("_border:", true);
        outputter("  .byte ", false);
        kalu = getpluscolor(int(g_map[0]));
        valu2 = getplusluminance(int(g_map[0]));
        valu = valu2 * 16 + kalu;
        outputter(valu + " ", true);
        outputter("_color:", true);
    }
    if (param == 5) {
        outputter("_lumi:", true);
    }
    for (y = 0; y < yy; y++) {
        //outputter("  .byte ", false);
        outputter(char(9) + ".db ", false);
        for (x = 0; x < xx; x++) {
            for (yline = 0; yline <= myrpsi; yline++) {
                ad = source + x + y * xoor + yline * xx;
                if (param == 0) {
                    valu = int(g_map[ad]);
                    valu2 = int(g_map[ad + MX * MY * 8]);
                }
                if (param == 1) {
                    valu2 = int(g_map[ad]);
                    valu = int(g_map[ad + 1000]);
                }
                if (param == 2) {
                    valu2 = int(g_map[ad]);
                    valu = 0;
                }
                if (param == 3) {
                    valu = int(g_map[ad]);
                    valu2 = int(g_map[ad + MX * MY * 8]);
                }

                if (param == 4) { //plus4 colortable
                    kalu = int(g_map[ad]);
                    valu = getpluscolor(kalu);
                    kalu = int(g_map[ad + MX * MY * 8]);
                    valu2 = getpluscolor(kalu);
                }

                if (param == 5) { //plus4 lumitable
                    kalu = int(g_map[ad]);
                    valu2 = getplusluminance(kalu);
                    kalu = int(g_map[ad + MX * MY * 8]);
                    valu = getplusluminance(kalu);
                }

                if (param == 6) { //plus4 multic1
                    valu2 = getpluscolor(int(g_map[ad]));
                    valu = getpluscolor(int(g_map[ad + 1000]));
                }

                if (param == 7) { //plus4 multic2
                    valu = getplusluminance(int(g_map[ad]));
                    valu2 = getplusluminance(int(g_map[ad + 1000]));
                }

                outputter(str(valu * 16 + valu2), false);
                mpWriteByte(int(valu * 16 + valu2));
                if (x < (xx - 1) || yline < myrpsi) {
                    outputter(",", false);
                }
            }
        }
        outputter("", true);
    }
    outputter("", true);
}

void import_program(String fname) {
    g_template = mpLoadBinaryFile(fname);
}

void export_program(String fname) {
    if (g_sorsaa != 1)
        mpSaveBinaryFile(fname, g_template);
}

void outputter(String oput, boolean eol) {
    if (g_sorsaa == 0) return;
    if (eol == false) exwriter.print(oput);
    if (eol == true) exwriter.println(oput);
}


void import_image(String name) {
    PImage image;
    image = loadImage(name);
    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;
    }
    ww = image.width;
    hh = image.height;
    if (ww <= 16 || hh <= 16) {
        return;
    }
    balx = int(ww / X);
    balx = balx * molox;
    baly = int(hh / 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(ww / X) * xx;
            y2 = int(hh / 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;
        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(ww / X) * xx;
                    y2 = int(hh / 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(ww / X) * xx;
                        y2 = int(hh / 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 mpRenderImageWithBorder()
{
    //output the visible graphics as image
    //with border
    //processing style
    PImage output = 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));

    return output;
}


PImage mpRenderImageWithoutBorder()
{
    //output the visible graphics as image
    //processing style
    //without border
    PImage 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);
    }
}