view multipaint.pde @ 40:8d2362b6ac12

Cleanups.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 04 Jul 2018 13:39:11 +0300
parents 5e0306ac3575
children df6eecdf1cd4
line wrap: on
line source

//
// Multipaint Metal Edition 22.5.2017
// Tero Heikkinen (Dr. TerrorZ)
// ProcessingJS port and changes by Matti Hämäläinen (ccr/TNSP)
// processing setup draw and file things here
//

PrintWriter exwriter;
final int C64 = 0, MSX = 5, SPECTRUM = 6, C64M = 10, PLUS4 = 9, PLUS4M = 19, CPC = 2; // supported
final int TIMEX = 7, JR200 = 8, AMIGA = 11; // experimental or incomplete
final int C64FLI = 20, C64FLIM = 21; // experimental
final int PICO8 = 88;
final int FAKEX = 32; // Commodore 64 without attribute limitations
final int UNIA = 33;
final int PEESEE = 0, MACOSX = 1, PSJS = 2;
//-1 & -1 for normal operation
int machine = -1; // change this to autoselect
int platform = PSJS;

final int COMMAND = 157; // Marq's cmd/ctrl solution

int g_active, g_tooltrigger, g_prevtool;
int g_rband, g_rbang, g_boxreconstruct, g_sorsaa, g_charlimit;
int g_animx, g_animy, g_animframes, g_animno, g_animtime, g_animspeed;
int g_omag, g_bordh, g_bordv, g_keymacpos, g_framec;

boolean fileselect = false, saveas = false, refselect = false, g_control = false, g_shift = false, exporttxt = false, importfmt = false, exportemu = false, exportfmt = false;
String path = "", refpath = "", filename = "", elename = "", sfilename = "", refname = "", g_expname = "";
String g_keymacro = "";

int[] g_r = new int[266];
int[] g_g = new int[266];
int[] g_b = new int[266];
int[] g_rgb = new int[266];

byte[] g_map = new byte[88000];
byte[] g_fillmap = new byte[88000];
byte[] g_sparepage = new byte[88000];
byte[] g_swappage = new byte[88000];
byte[] g_rmap = new byte[88000];
byte[] g_icons = new byte[88000];
byte[] g_brush = new byte[88000];
byte[][] g_undob = new byte[11][88000];
byte[][] g_undobs = new byte[11][88000];
byte[] g_template = new byte[16384];
byte[] g_redo = new byte[1024];
byte[] g_remdo = new byte[1024];
int[] g_chaup = new int[64];
byte[] g_data = new byte[1024];
int[] g_uindex = new int[8];
int[] g_ubottom = new int[8];
int[] g_utop = new int[8];
int[] g_magpix = new int[64];
int[] g_magpiy = new int[64];

byte g_realfront, g_realback;
PImage output, outputsans;
String g_name;

//dimensions
int X, Y, MX, MY;
//generic mouse
int g_ofx, g_ofy, g_button, g_realbutton, g_klikkeri, g_mx, g_my, g_orx, g_ory, g_msx, g_msy;
//rubberband,mouse
int g_phase, g_rx, g_ry, g_rx2, g_ry2, g_rubbermode;
int g_prex, g_prey, g_storedcoordx, g_storedcoordy;
//window positioning
int g_windowx, g_windowy, g_maglocx, g_maglocy;
int g_hedge, g_vedge, g_uizoom, g_wzoom;
//icons & gui stuff
int g_iconx, g_icony, g_piconx, g_picony, g_iconmode;
int g_gridx, g_gridy, g_spare;
int g_farge, g_backg, g_ofarge, g_repanel, g_msgctr;
//machine related color properties
int g_attrimode, g_britemode, g_multic, g_backmode, g_maxcolors, g_hzoomer;
float g_palsteps;
//brush, tool parameters
int g_bsourcex, g_bsourcey, g_bsourcex2, g_bsourcey2;
int g_bsize, g_btype;


void setup() {
    int i, x, y;

    frameRate(40);

    for (i = 0; i < g_data.length; i++)
        g_data[i] = 0;

    g_magpix[0] = 3;
    g_magpix[1] = 8;
    g_magpix[2] = 16;
    g_magpix[10] = 2;
    g_magpix[11] = 6;
    g_magpix[12] = 16;
    g_magpix[20] = 4;
    g_magpix[21] = 16;
    g_magpix[22] = 32;

    g_magpiy[0] = 3;
    g_magpiy[1] = 8;
    g_magpiy[2] = 16;
    g_magpiy[10] = 2;
    g_magpiy[11] = 6;
    g_magpiy[12] = 16;
    g_magpiy[20] = 4;
    g_magpiy[21] = 16;
    g_magpiy[22] = 32;

    g_omag = 1;
    g_bordh = 64;
    g_bordv = 32;

    // Set up UI
    g_uizoom = 2;
    g_animspeed = 1;

    // Get machine from Javascript runner, or default to C64
    if (mpMachine)
        machine = mpMachine;
    else
        machine = C64;

    switch (g_uizoom) {
        case 1:
            g_wzoom = 2;
            size(700, 468);
            break;
        case 2:
            g_wzoom = 3;
            size(1058, 708);
            break;
        case 3:
            g_wzoom = 4;
            size(1460, 950);
            break;
    }

    g_hedge = 32 * g_uizoom;
    g_vedge = 32 * g_uizoom;

    g_uindex[0] = 0;
    g_utop[0] = 0;
    g_ubottom[0] = 0;
    g_uindex[1] = 0;
    g_utop[1] = 0;
    g_ubottom[1] = 0;
    g_spare = 0;
    g_bsize = 0;
    g_btype = 0;
    g_phase = 0;
    g_button = LEFT;
    g_data[int('f')] = 1;
    g_data[int('g')] = 1;
    g_icons = mpLoadBinaryFile("icons.bin");
    set_tool(3);

    g_gridx = 8;
    g_gridy = 8;
    g_multic = 0;
    g_repanel = -2;

    //UI colors
    makecolor(256, 0xff, 0, 0xff);
    makecolor(257, 180, 180, 180);
    g_rgb[257] = 0xff808080;
    makecolor(258, 0, 0, 0);
    makecolor(259, 48, 48, 48);
    //R,G,B
    makecolor(260, 255, 0, 0);
    makecolor(261, 0, 255, 0);
    makecolor(262, 0, 0, 255);

    set_machine(machine);
    g_windowx = width - (g_hedge) - (g_wzoom * X);
    g_windowx = int(g_windowx / 2);
    g_windowy = height - (g_vedge) - (g_wzoom * Y);
    g_windowy = int(g_windowy / 2);

    switcher(3);

    g_map[4] = byte(g_maxcolors - 1);
    g_ofarge = g_farge;
    MX = int(X / 8);
    MY = int(Y / 8);
    g_realfront = byte(g_farge);
    g_realback = byte(g_backg);

    output = createImage(X * g_omag + g_bordh * g_omag, Y * g_omag + g_bordv * g_omag, RGB);
    outputsans = createImage(X * g_omag, Y * g_omag, RGB);

    for (y = 0; y < Y; y++) {
        for (x = 0; x < X; x++) {
            absolute_clearpoint(x, y);
        }
    }

    switcher(2);
    noStroke();
    background(g_r[259], g_g[259], g_b[259]);
    sussborder();
    setup_raster();
    message("Multipaint|Metal|v22.5.2017");
    message("*");
}


void mpSetTitle(String str) {
    console.log("TITLE: '" + str + "'");
}


boolean fexists(String fname) {
    //  File f = new File(fname);
    //  if (f.exists())return true;
    return true;
}


function mpLoadFileSelector(ftypes, callback)
{
    var mpUI = stGE("mpUI");
    if (mpUI)
    {
        stClearChildren(mpUI);
        mpUI.style.background = "red";
        mpUI.style.padding = "0.5em";

        var mobj = stCE("input", "mpFileSelector");
        mobj.type = "file";
        mobj.name = "name";
        mobj.multiple = false;

        if (ftypes != null)
            mobj.accept = ftypes;

        stAddEventOb(mobj.name, mobj, "change",
            function(evt)
            {
                var files = evt.target.files;
                if (files.length > 0)
                {
                    var freader = new FileReader();

                    freader.onloadend = (function(theFile) {
                        callback(theFile, new Uint8Array(freader.result));
                    });

                    freader.readAsArrayBuffer(files[0]);
                }
                stClearChildren(mpUI);
                mpUI.style.background = null;
            });

        mpUI.appendChild(mobj);
    }
    else
        return null;
}


byte[] mpLoadBinaryFile(String url)
{
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, false);
    xhr.overrideMimeType("text/plain; charset=x-user-defined");
    xhr.setRequestHeader("If-Modified-Since", "Fri, 01 Jan 1960 00:00:00 GMT");
    xhr.send(null);

    if (xhr.status !== 200 && xhr.status !== 0)
        return null;

    var string = xhr.responseText;
    byte[] ret = new byte[string.length];

    for (var i = 0; i < string.length; i++)
    {
        ret[i] = string.charCodeAt(i) & 0xff;
    }

    return ret;
}


void mpSaveBinaryFile(String name, byte[] data)
{
    var blob = new Blob([new Uint8Array(data)], {type: "application/octet-stream"}),
        url = window.URL.createObjectURL(blob);

    var alink = stCE("a");
    var mpUI = stGE("mpUI");
    stClearChildren(mpUI);
    mpUI.appendChild(alink);

    alink.style = "display: none";
    alink.href = url;
    alink.download = name;
    alink.click();

    window.URL.revokeObjectURL(url);
}


void mpSavePNGImage(String name)
{
    if (g_data[int('Q')] == 0)
        export_image_sans_border(name);
    else
        export_image(name);
}


void mpLoadPNGImage(String name)
{
    int lefth = g_farge;
    int righth = g_backg;
    storeparameters();

    g_data[int('d')] = 0;
    g_data[int('t')] = 0;
    g_data[int('b')] = 1; //old IQ

    import_image(name);

    restoreparameters();
    refreshpalette();
    refresh();
    g_boxreconstruct = 2;
    message("Image|loaded");
    selectcolor(0, lefth);
    selectcolor(1, righth);
}


void mpSaveNativeImage(String name) {
    //save the picture page g_map[], make sure some essential parameters are correct
    g_map[3] = byte(machine);
    g_map[5] = byte(MX);
    g_map[7] = byte(MY);

    mpSaveBinaryFile(name, g_map);
}


void mpSetNativeImage(byte[] data, bool noError)
{
    if (data == null) {
        message("NO FILE");
        return false;
    }

    if (data[3] != machine && !noError) {
        message("Wrong|machine!");
        return false;
    }

    g_map = data;

    refreshpalette();
    consistency();
    g_farge = int(g_realfront);
    g_ofarge = g_farge;
    g_backg = int(g_realback);
    sussborder();

    return true;
}


bool mpLoadNativeImage(String name, bool noError) {
    //load the picture page g_map[] with parameters
    byte[] data = mpLoadBinaryFile(name);

    if (!mpSetNativeImage(data, noError))
        return false;

    message("Page|loaded");
    return true;
}


void draw() {
    if (!focused) {
        g_control = false;
        g_shift = false;
    }

    if (g_data[int('n')] == 1) {
        g_animtime++;
        if (g_animtime > 8 - g_animspeed * 2) {
            animbrush_do();
            g_animtime = 0;
        }
    }

    if (moicon(16 * 16 * g_uizoom, height - 32 * g_uizoom, 16 * g_uizoom, 24 * g_uizoom)) help(int('<'));
    if (moicon(16 * 16 * g_uizoom, height - 8 * g_uizoom, 16 * g_uizoom, 8 * g_uizoom)) help(int('>'));
    if (moicon(0, height - 32 * g_uizoom, 15 * 16 * g_uizoom, 32 * g_uizoom)) help(TAB);
    if (moicon(width - 32 * g_uizoom, 0, 32 * g_uizoom, 16 * g_uizoom)) help(int('.'));

    // Update some mouse variables
    if (g_data[int('m')] == 0 && g_data[int('M')] == 0) {
        g_mx = g_msx - g_windowx;
        g_my = g_msy - g_windowy;
    } else {
        g_mx = mouseX;
        g_my = mouseY;
    }

    g_msx = mouseX;
    g_msy = mouseY;

    // Actual tool drawing
    if (g_tooltrigger == 1) { // comes from mousepressed, or mousedragged
        if (g_mx <= width - g_hedge && g_my <= height - g_vedge)
            do_tool(g_mx, g_my, g_button);
    }

    switcher(0);

    for (int i = 0; i < 1024; i++) {
        g_remdo[i] = 0;
    }

    // Tool drawing for shows
    int lipo = g_button;
    if (tool() != 5) {
        if (g_phase == 0)
            g_button = LEFT;
        do_tool(g_mx, g_my, LEFT);
    }
    if (tool() == 6) doline(g_rx, g_ry, g_rx2, g_ry2, 0);
    if (tool() == 7) docircle(g_rx, g_ry, g_rx2, g_ry2);
    if (tool() == 8) rectangle(g_rx, g_ry, g_rx2, g_ry2);
    g_button = lipo;

    // Screen update stuff
    loadPixels();
    viewport();
    //magport();
    switcher(1);
    update_ui();
    updatePixels();

    if (g_msgctr > 0)
        g_msgctr--;

    // UI file operations
    if (fileselect) // Fileselect "event" for Load
    {
        mpLoadFileSelector(".mpe, .MPE",
        function (fh, fdata)
        {
            if (mpSetNativeImage(fdata))
            {
                store_undo();
                mpSetTitle(fh.name);
                if (g_spare == 0)
                    filename = fh.name;
                else
                    sfilename = fh.name;

                refresh();
            }
        });

        fileselect = false;
        g_shift = false;
        g_control = false;
    }

    if (saveas) // Fileselect "event" for Save as
    {
        String s = fileselector(path, SAVEIMG);
        String orig = "";
        int kuva = 0;
        if (g_spare == 0) orig = filename;
        if (g_spare == 1) orig = sfilename;

        if (s != null) {
            // Add extension if needed
            if (s.length() <= 2) s += ".bin";
            s = s + ".dummy.dummy";
            String[] l = split(s, '.');
            String[] m1 = match(l[1], "png");
            String[] m2 = match(l[1], "PNG");
            String[] m3 = match(l[1], "bin");
            String[] m4 = match(l[1], "BIN");
            if (m1 != null || m2 != null) kuva = 1;
            if (m1 == null && m2 == null && m3 == null && m4 == null) l[1] = "bin";

            if (g_spare == 0) {
                filename = l[0] + "." + l[1];
                mpSavePNGImage(filename);
                if (kuva == 1) filename = orig;
                mpSetTitle(filename);
            } else {
                sfilename = l[0] + "." + l[1];
                mpSavePNGImage(sfilename);
                if (kuva == 1) sfilename = orig;
                mpSetTitle(sfilename);
            }

            message("SAVED");
            if (kuva == 1) message("EXPORTED|PNG");
        }
        saveas = false;
        g_shift = false;
        g_control = false;
    }

    if (exporttxt) {
        if (g_spare == 0) {
            exportemuname = filename + "." + l[1];
        } else {
            exportemuname = sfilename + "." + l[1];
        }

        machine_export(exportemuname, 1);

        exporttxt = false;
        g_shift = false;
        g_control = false;
    }

    if (exportemu) {
        if (g_spare == 0) {
            exportemuname = filename + "." + l[1];
        } else {
            exportemuname = sfilename + "." + l[1];
        }

        machine_export(exportemuname, 0);

        exportemu = false;
        g_shift = false;
        g_control = false;
    }

    if (importfmt) {
        mpLoadFileSelector(".aas, .AAS",
        function (fh, fdata)
        {
            store_undo();
            filename = fh.name;
            format_import(fdata);
            refresh();
        });

        importfmt = false;
        g_shift = false;
        g_control = false;
    }

    if (exportfmt) {
        format_export(filename +"_"+ (g_spare ? "spare" : "main") +".aas");

        exportfmt = false;
        g_shift = false;
        g_control = false;
    }

    //if(g_framec==1){saveFrame("frames/out-######.png");}
    //g_framec++;if(g_framec>1)g_framec=0;

    if (g_keymacro.length() > g_keymacpos) {
        macro_command(g_keymacro.charAt(g_keymacpos));
        g_keymacpos++;
    }
}