view exporters.pde @ 124:68e8d86c9eef

Get rid of unused variables and clean up the logic slightly in mpExportColorData()
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 09 Jul 2018 19:34:36 +0300
parents ffa6533584ca
children c210b2e2cb47
line wrap: on
line source

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


public class MPWriteCtx
{
    public int m_offs, m_bpl, m_bytes, m_indent;
    public String m_byteDef, m_eol, m_src;
    public byte[] data;

    MPWriteCtx()
    {
        m_offs = 0;
        m_bpl = 32;
        m_bytes = 0;
        m_indent = 4;
        m_byteDef = ".byte";
        m_src = "";
        m_eol = "\n";
        m_data = new byte[1*1024];
    }

    void setOffs(int offs)
    {
        m_offs = offs;
    }

    void setBPL(int bpl)
    {
        m_bpl = bpl;
    }

    byte[] getData()
    {
        return m_data;
    }

    byte[] getSource()
    {
        return m_src;
    }

    String getIndent()
    {
        String str = "";
        for (int n = 0; n < m_indent; n++)
            str += " ";
        return str;
    }

    void label(String blabel)
    {
        eol();
        m_src += blabel +":";
        eol();
        m_bytes = 0;
    }

    void comment(String bstr)
    {
        indent();
        m_src += "; "+ bstr;
        eol();
    }

    void eol()
    {
        m_src += m_eol;
    }

    void eod()
    {
        eol();
        eol();
    }

    void byteDef()
    {
        m_src += m_byteDef +" ";
    }

    void byteSep()
    {
        m_src += ",";
    }

    void indent()
    {
        m_src += getIndent();
    }

    void line(String str)
    {
        m_src += str;
        eol();
    }

    void writeByte(int bval, String blabel)
    {
        m_data[m_offs++] = byte(bval);

        if (blabel != null)
        {
            m_src += blabel +": "+ m_byteDef +" "+ str(int(bval)) + m_eol;
        }
        else
        {
            m_src += str(int(bval));

            if (m_bpl > 0 &&
                ++m_bytes >= m_bpl)
            {
                eol();
                indent();
                byteDef();
                m_bytes = 0;
            }
            else
                m_src += ",";
        }
    }

    void writeByteAt(int boffs, int bval, String blabel)
    {
        m_offs = boffs;
        writeByte(bval, blabel);
    }

    void loadTemplate(String fname)
    {
        m_data = mpLoadBinaryFile("templates/" + fname);
    }
}


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


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;
}


bool mpExportFormat(MPWriteCtx ctx, int subformat)
{
    int val1, val2, val3;
    int y, y2, yy, x, yp, xp, ad, valu, valu2, bri;

    if (machine == PLUS4) { // botticelli hires
        ctx.loadTemplate("g.hires.prg");

        ctx.setOffs(0x02);
        mpExportColorData(ctx, 40, 25, 65536, 5); //lumis

        ctx.setOffs(1026);
        mpExportColorData(ctx, 40, 25, 65536, 4); //colors

        ctx.setOffs(2050);
        mpExportBitmapData(ctx, 40, 25);
    }
    else
    if (machine == PLUS4M) { // multi botticelli multicolor
        ctx.loadTemplate("m.multi.prg");

        val2 = getpluscolor(int(g_map[1]));
        val1 = getplusluminance(int(g_map[1]));
        val3 = val2 * 16 + val1;
        ctx.writeByteAt(1025, val3);

        val2 = getpluscolor(int(g_map[2]));
        val1 = getplusluminance(int(g_map[2]));
        val3 = val2 * 16 + val1;
        ctx.writeByteAt(1024, val3);

        ctx.setOffs(1026);
        mpExportColorData(ctx, 40, 25, 65536, 6); //colors

        ctx.setOffs(2);
        mpExportColorData(ctx, 40, 25, 65536, 7); //lumis

        ctx.setOffs(2050);
        mpExportBitmapData(ctx, 40, 25);
    }
    else
    if (machine == C64) {
        ctx.loadTemplate("hires.art");

        ctx.setOffs(2);
        mpExportBitmapData(ctx, 40, 25);

        ctx.setOffs(0x1f42);
        mpExportColorData(ctx, 40, 25, 65536, 0);

        ctx.writeByteAt(0x232a, g_map[0]);
    }
    else
    if (machine == C64M) {
        if (subformat == 0)
        {
            // Advanced Art Studio
            ctx.loadTemplate("multic.ocp");

            ctx.setOffs(2);
            mpExportBitmapData(ctx, 40, 25);

            ctx.setOffs(0x1f42);
            mpExportColorData(ctx, 40, 25, 65536, 1);

            ctx.setOffs(0x233a);
            mpExportColorData(ctx, 40, 25, 65536 + 2000, 2);

            ctx.writeByteAt(0x232a, g_map[0]);
            ctx.writeByteAt(0x232b, g_map[1]);
        }
        else
        {
            // Koala Painter
            ctx.loadTemplate("multic.kla");

            ctx.setOffs(2);
            mpExportBitmapData(ctx, 40, 25);

            ctx.setOffs(0x1f42);
            mpExportColorData(ctx, 40, 25, 65536, 1);

            ctx.setOffs(0x232a);
            mpExportColorData(ctx, 40, 25, 65536 + 2000, 2);

            ctx.writeByteAt(0x2712, g_map[1] & 0x0f);
        }
    }
    else
    if (machine == MSX) {
        ctx.loadTemplate("msx-screen2.sc2");

        ctx.setOffs(7);
        mpExportBitmapData(ctx, 32, 24);

        ctx.setOffs(7 + (32 * 24 * 8) + 768 + 1280);
        mpExportColorData(ctx, 32, 24, 65536, 3); //there's an exception for msx-style
    }
    else
    if (machine == SPECTRUM) {
        ctx.loadTemplate("zx-screen.scr");

        ctx.setOffs(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;

            ctx.writeByte(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;
            }
            ctx.writeByte(valu + valu2 * 8);
        }
    }
    else
        return false;

    return true;
}


bool mpExportMachinePRG(MPWriteCtx ctx)
{
    // any common text headers
    ctx.comment("machine=" + str(machine) + " (" + g_name + ")");

    if (machine == C64) { //C64 HIRES
        ctx.loadTemplate("c64show.prg");

        ctx.setOffs(0x0227);
        ctx.label("_bitmap");
        mpExportBitmapData(ctx, 40, 25);

        ctx.comment("The following two first values are border and background");
        ctx.writeByteAt(0x2167, g_map[0]); //=border
        ctx.writeByteAt(0x2168, g_map[1]); //=background mutta ei tarvita

        ctx.setOffs(0x2169);
        mpExportColorData(ctx, 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

        ctx.loadTemplate("c64mshow.prg");
        ctx.setOffs(0x0239);
        mpExportBitmapData(ctx, 40, 25);

        // first color information
        ctx.comment("The following two first values are border and background");
        ctx.writeByteAt(0x2179, g_map[0]);
        ctx.writeByteAt(0x217a, g_map[1]);

        ctx.setOffs(0x217B);
        mpExportColorData(ctx, 40, 25, 65536, 1);

        // second color information
        ctx.setOffs(0x2563);
        ctx.comment("The following goes to $D800 onwards");
        mpExportColorData(ctx, 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
        ctx.loadTemplate("showpfourm.prg");

        ctx.line(".global _bitmap");
        ctx.line(".global _color1");
        ctx.line(".global _color2");
        ctx.line(".global _border");
        ctx.line(".global _back1");
        ctx.line(".global _back2");

        ctx.label("_bitmap");
        ctx.setOffs(0x013e);
        mpExportBitmapData(ctx, 40, 25);

        val1 = getpluscolor(int(g_map[0]));
        val2 = getplusluminance(int(g_map[0]));
        val3 = val2 * 16 + val1;
        ctx.label("_border");
        ctx.setOffs(0x207e);
        ctx.writeByte(val3);

        val1 = getpluscolor(int(g_map[1]));
        val2 = getplusluminance(int(g_map[1]));
        val3 = val2 * 16 + val1;
        ctx.label("_back1");
        ctx.setOffs(0x207f);
        ctx.writeByte(val3);

        val1 = getpluscolor(int(g_map[2]));
        val2 = getplusluminance(int(g_map[2]));
        val3 = val2 * 16 + val1;
        ctx.label("_back2");
        ctx.setOffs(0x2080);
        ctx.writeByte(val3);

        ctx.label("_color1");
        ctx.setOffs(0x2081);
        mpExportColorData(ctx, 40, 25, 65536, 6);

        ctx.label("_color2");
        ctx.setOffs(0x2469);
        mpExportColorData(ctx, 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
        ctx.loadTemplate("showpfour.prg");

        ctx.line(".global _bitmap");
        ctx.line(".global _color");
        ctx.line(".global _lumi");
        ctx.line(".global _border");

        ctx.setOffs(0x0137);
        mpExportBitmapData(ctx, 40, 25);

        val1 = getpluscolor(int(g_map[0]));
        val2 = getplusluminance(int(g_map[0]));
        val3 = val2 * 16 + val1;
        ctx.setOffs(0x2077);
        ctx.writeByte(val3); //border

        ctx.setOffs(0x2078);
        mpExportColorData(ctx, 40, 25, 65536, 4); //colors

        ctx.setOffs(0x2460);
        mpExportColorData(ctx, 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
        ctx.loadTemplate("msxshow.com");
        ctx.line(".globl _bitmap,_nimi2");
        ctx.line(".area _CODE");

        ctx.setOffs(0x00f9);
        ctx.label("_bitmap");
        mpExportBitmapData(ctx, 32, 24);


        //ctx.writeByte(g_map[1]); //backg
        //ctx.comment("The first following value is background");
        ctx.label("_nimi2");
        ctx.setOffs(0x18f9);
        mpExportColorData(ctx, 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

        //  ctx.line(".area  _DATA\n";
        //  ctx.line(".globl _taustakuva\n\n";
        //  ctx.label("_taustakuva");
        ctx.loadTemplate("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));
        ctx.setOffs(0x0223);
        ctx.byteDef();
        ctx.writeByte(g_map[0]);
        checksum = checksum ^ int(g_map[0]);

        for (int y = 0; y <= 2; y++)
        for (int y2 = 0; y2 < 8; y2++)
        for (int yy = 0; yy < 8; yy++)
        {
            for (int x = 0; x < 32; 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;

                ctx.writeByte(valu);
                checksum = checksum ^ int(valu);
            }
        }

        ctx.comment("attributes");
        for (int y = 0; y < 24; y++)
        {
            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;
                }

                ctx.writeByte(valu + valu2 * 8);
                checksum = checksum ^ int(valu + valu2 * 8);
            }
        }

        //println("checksum:"+hex(checksum,2));
        ctx.writeByteAt(0x1d3e, int(checksum));
    }
    else
    if (machine == CPC) {
        int val1, val2, val3, valu;
        ctx.loadTemplate("cpc-mode0.bin");

        ctx.setOffs(69); //bitmap offset
        ctx.label("_bitmap");
        mpExportBitmapData_CPC(ctx, 160, 200);

        //fixed # of palette entries, just trying to be generic
        ctx.setOffs(16453);
        ctx.setBPL(g_maxcolors - 1);
        ctx.label("_palette");
        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));

            ctx.writeByte(ctx, val1 * 9 + val2 * 3 + val3);
        }

        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));

        ctx.label("_border");
        ctx.setOffs(16469);
        ctx.writeByte(val1 * 9 + val2 * 3 + val3);

        //cpc
        //69    bitmap 16384 bytes
        //16453 palette 16 bytes (0..26)
        //16469 border color (0..26)
    }
    else
        return false;

    return true;
}


void mpExportBitmapData_CPC(MPWriteCtx ctx, int xwid, int yy)
{
    int x, y, ad, val1, val2, y2;
    int pix0b0, pix0b1, pix0b2, pix0b3;
    int pix1b0, pix1b1, pix1b2, pix1b3;

    ctx.setBPL(xwid / 2);
    ctx.byteDef();

    for (y2 = 0; y2 < 8; y2++)
    {
        for (y = 0; y < 25; y++)
        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;

            ctx.writeByte(val2);
        }

        ctx.byteDef();
        for (int j = 0; j <= 47; j++)
            ctx.writeByte(0);
        ctx.eol();
    }
    ctx.eod();
}


void mpExportBitmapData(MPWriteCtx ctx, int xx, int yy)
{
    int linep = 0,
        xwid  = xx * 8,
        ywid = yy * 8;

    ctx.setBPL(64);
    ctx.byteDef();
    for (int y = 0; y < yy; y++)
    for (int x = 0; x < xx; x++)
    {
        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;

            ctx.writeByte(int(value));
        }
    }
    ctx.eod();
}


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;
}


void mpExportColorData(MPWriteCtx ctx, int width, int height, int srcoffs, int param)
{
    int xmult, myrpsi;

    myrpsi = 0;

    if (param == 0 || param == 3 || param == 4 || param == 5)
        xmult = width * 8;
    else
        xmult = width;

    if (machine == MSX) {
        myrpsi = 7;
    }

    for (int yc = 0; yc < height; yc++)
    {
        ctx.byteDef();
        for (int xc = 0; xc < width; xc++)
        for (int yline = 0; yline <= myrpsi; yline++)
        {
            int valu1, valu2, ad = srcoffs + xc + yc * xmult + yline * width;

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

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

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

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

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

                case 5:
                    //plus4 lumitable
                    valu1 = 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]));
                    valu1 = getpluscolor(int(g_map[ad + 1000]));
                    break;

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

                default:
                    return null;
            }

            ctx.writeByte(valu1 * 16 + valu2);
        }
        ctx.eol();
    }
}


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