view multipaint.pde @ 7:c848a6133cfc

Fix many calculations (divisions) that assume integer variable division semantics by truncating to int(). Also add two helper functions chop2(v) and chop8(v) and use them where appropriate.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 03 Jul 2018 22:17:48 +0300
parents a1261cd4c676
children dfdc18b62fab
line wrap: on
line source

//Multipaint Metal Edition 22.5.2017
//Tero Heikkinen (Dr. TerrorZ)
//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;

//-1 & -1 for normal operation
int machine = -1; // change this to autoselect
int debugger = -1;

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 gui = true, 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 = "", g_fmtname = "";
String exporttxtname = "", exportemuname = "", exportfmtname;
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() {
    //  size(1058,708);//processing3
    int i, x, y;
    g_uizoom = 2;
    g_animspeed = 1;
    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;
    readprefs("prefs.txt");

    //processing 2
    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;
    }
    /*
    //processing 3
    switch (g_uizoom){
      case 1:  g_wzoom=2;surface.setSize(700,468);break;
      case 2:  g_wzoom=3;surface.setSize(1058,708);break;
      case 3:  g_wzoom=4;surface.setSize(1460,950);break;
    }
    */

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

    if (machine == -1 || debugger == 0) {
        if (gui) {
            try {
                UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
            } catch (Exception e) {};
            machine = selector("Select a Platform", "C64 hires,C64 multicolor,ZX Spectrum,MSX1 mode 2,Plus4 hires,Plus4 multicolor,Amstrad CPC mode 0");
        }
        switch (machine) {
            case 0:
                machine = C64;
                break;
            case 1:
                machine = C64M;
                break;
            case 2:
                machine = SPECTRUM;
                break;
            case 3:
                machine = MSX;
                break;
            case 4:
                machine = PLUS4;
                break;
            case 5:
                machine = PLUS4M;
                break;
            case 6:
                machine = CPC;
                break;
            default:
                ;
        }
    }

    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;
    if (fexists("icons.bin") == true) g_icons = loadBytes("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 store(String name) {
    String[] m1 = match(name, ".png");
    if (m1 != null) {
        if (g_data[int('Q')] == 0) {
            export_image_sans_border(name);
        }
        if (g_data[int('Q')] == 1) {
            export_image(name);
        }
        return;
    }

    //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);
    saveBytes(name, g_map);
}

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

void restore(String name) {
    //load the picture page g_map[] with parameters
    boolean im_import = false;
    if (fexists(name) == false) {
        message("NO FILE");
        return;
    }
    String[] m1 = match(name, ".png");
    if (m1 != null) im_import = true;
    String[] m2 = match(name, ".PNG");
    if (m2 != null) im_import = true;
    String[] m3 = match(name, ".jpg");
    if (m3 != null) im_import = true;
    String[] m4 = match(name, ".JPG");
    if (m4 != null) im_import = true;

    if (im_import) {
        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);
        return;
    }
    g_map = loadBytes(name);
    if (g_map[3] != machine) {
        message("Wrong|machine!");
        restore_undo();
        return;
    }
    refreshpalette();
    consistency();
    g_farge = int(g_realfront);
    g_ofarge = g_farge;
    g_backg = int(g_realback);
    sussborder();
    message("Page|loaded");
}

void draw() {
    int msx, msy;

    if (!focused) {
        g_control = false;
        g_shift = false;
        delay(200);
    }

    if (g_data[int('n')] == 1) {
        g_animtime++;
        if (g_animtime > 8 - g_animspeed * 2) {
            animbrush_do();
            g_animtime = 0;
        }
    }
    /*
    boolean depis=false;
    for(int i=0;i<=255;i++){
      if(g_depressed[i]>0){
        g_depressed[i]--;
        if(g_depressed[i]==0)depis=true;
      }
    }
    if(depis)g_repanel=-2;
    */
    if (moicon(16 * 16 * g_uizoom, height - 32 * g_uizoom, 16 * g_uizoom, 24 * g_uizoom)) help('<');
    if (moicon(16 * 16 * g_uizoom, height - 8 * g_uizoom, 16 * g_uizoom, 8 * g_uizoom)) help('>');
    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('.');

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

    //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(msx, msy, g_button);
    }
    g_msx = mouseX;
    g_msy = mouseY;
    switcher(0);

    for (int i = 0; i < 1024; i++) {
        g_remdo[i] = 0;
    }
    int lipo = g_button;
    //tool drawing for shows
    if (tool() != 5) {
        if (g_phase == 0) g_button = LEFT;
        do_tool(msx, msy, 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;
    loadPixels();
    viewport();
    //magport();
    switcher(1);
    update_ui();
    updatePixels();
    if (g_msgctr > 0) g_msgctr--;

    // UI file operations
    if (gui) {
        if (fileselect) // Fileselect "event" for Load
        {
            String s = fileselector(path, LOADIMG);
            if (s != null) {
                store_undo();
                if (g_spare == 0) {
                    filename = s;
                    frame.setTitle(filename);
                    restore(s);
                }
                if (g_spare == 1) {
                    restore(s);
                    sfilename = s;
                    frame.setTitle(sfilename);
                }
                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];
                    store(filename);
                    if (kuva == 1) filename = orig;
                    frame.setTitle(filename);
                }
                if (g_spare == 1) {
                    sfilename = l[0] + "." + l[1];
                    store(sfilename);
                    if (kuva == 1) sfilename = orig;
                    frame.setTitle(sfilename);
                }

                message("SAVED");
                if (kuva == 1) message("EXPORTED|PNG");
            }
            saveas = false;
            g_shift = false;
            g_control = false;
        }
        if (exporttxt) {
            String s = fileselector(path, SAVETXT);
            if (s != null) {
                // Add extension if needed
                if (s.length() <= 2) s += ".txt";
                s = s + ".dummy.dummy";
                String[] l = split(s, '.');
                l[1] = "txt";
                if (g_spare == 0) {
                    exportemuname = l[0] + "." + l[1];
                    machine_export(exportemuname, 1);
                }
                if (g_spare == 1) {
                    exportemuname = l[0] + "." + l[1];
                    machine_export(exportemuname, 1);
                }
            }
            exporttxt = false;
            g_shift = false;
            g_control = false;
        }
        if (exportemu) {
            String s = fileselector(path, SAVEEMU);
            if (s != null) {
                // Add extension if needed
                if (s.length() <= 2) s += "." + g_expname;
                s = s + ".dummy.dummy";
                String[] l = split(s, '.');
                l[1] = g_expname;
                if (g_spare == 0) {
                    exportemuname = l[0] + "." + l[1];
                    machine_export(exportemuname, 0);
                    //println(exportemuname);
                }
                if (g_spare == 1) {
                    exportemuname = l[0] + "." + l[1];
                    machine_export(exportemuname, 0);
                }

                //message("EXPORTED");
            }
            exportemu = false;
            g_shift = false;
            g_control = false;
        }
        if (importfmt) {
            String s = fileselector(path, LOADFMT);
            if (s != null) {
                store_undo();
                format_import(s);
                refresh();
            }
            importfmt = false;
            g_shift = false;
            g_control = false;
        }
        if (exportfmt) {
            String s = fileselector(path, SAVEFMT);
            if (s != null) {
                boolean koalakludge = false;
                // Add extension if needed
                if (s.indexOf(".kla") > -1 && machine == C64M) koalakludge = true;
                if (s.length() <= 2) s += "." + g_fmtname;
                s = s + ".dummy.dummy";
                String[] l = split(s, '.');
                l[1] = g_formatextension;

                if (koalakludge) l[1] = "kla";

                if (g_spare == 0) {
                    exportfmtname = l[0] + "." + l[1];
                    format_export(exportfmtname);
                    //println(exportemuname);
                }
                if (g_spare == 1) {
                    exportfmtname = l[0] + "." + l[1];
                    format_export(exportfmtname);
                }

                //message("EXPORTED");
            }
            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++;
    }
}